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.])]
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
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
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 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
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 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)
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
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
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)
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')
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)
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))
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
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)
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))
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
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)
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
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'])
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())
#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:
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)
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
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",
'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()
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()
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
###### 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)
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
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
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]
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]
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)
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)
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')
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
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')
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))
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
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')
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
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))
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))
( 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,
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