def build_crack_cell(self, unit_slab, pot, fix_dist=1.0): """ Creates a CrackCell of the desired size and orientation with the top and bottom layer of atoms constrained. Returns: :class:`Atoms` - the relaxed crack_cell. """ self.nx = int(self.width/unit_slab.get_cell()[0,0]) self.ny = int(self.height/unit_slab.get_cell()[1,1]) if self.ny %2 == 1: self.ny +=1 #self.ny = 1 print 'number of unit cells', self.nx, self.ny crack_slab = unit_slab*(self.nx, self.ny,self.nz) write('ref_slab.xyz', crack_slab) crack_slab.center(self.vacuum, axis=0) crack_slab.center(self.vacuum, axis=1) crack_slab.positions[:, 0] -= crack_slab.positions[:, 0].mean() crack_slab.positions[:, 1] -= crack_slab.positions[:, 1].mean() self.orig_width = (crack_slab.positions[:, 0].max() - crack_slab.positions[:, 0].min()) self.orig_height = (crack_slab.positions[:, 1].max() - crack_slab.positions[:, 1].min()) print(('Made slab with %d atoms, original width and height: %.1f x %.1f A^2' % (len(crack_slab), self.orig_width, self.orig_height))) top = crack_slab.positions[:,1].max() bottom = crack_slab.positions[:,1].min() left = crack_slab.positions[:,0].min() right = crack_slab.positions[:,0].max() #Constrain top and bottom layer of atoms: fixed_mask = ((abs(crack_slab.positions[:, 1] - top) < 1.0) | (abs(crack_slab.positions[:, 1] - bottom) < 1.0)) const = FixAtoms(mask=fixed_mask) crack_slab.set_constraint(const) #Strain is a dimensionless ratio we require elastic tensor #to translate the initial energy flow to the tip into a strain. self.E = youngs_modulus(self.cij, self.cleavage_plane) self.nu = poisson_ratio(self.cij, self.cleavage_plane, self.crack_direction) self.strain = G_to_strain(self.initial_G, self.E, self.nu, self.orig_height) seed = left + self.crack_seed_length tip = left + self.crack_seed_length + self.strain_ramp_length xpos = crack_slab.positions[:,0] ypos = crack_slab.positions[:,1] crack_slab.positions[:,1] += thin_strip_displacement_y(xpos, ypos, self.strain, seed, tip) write('crack_slab_init.xyz', crack_slab) print('Applied initial load: strain=%.4f, G=%.2f J/m^2' % (self.strain, self.initial_G / (units.J / units.m**2))) pot_dir = os.environ['POTDIR'] crack_slab.set_calculator(pot) #Initial crack pos print 'crack_pos before relaxations' print find_crack_tip_stress_field(crack_slab, calc=mm_pot) print('Relaxing slab...') slab_opt = PreconFIRE(crack_slab) slab_opt.run(fmax=self.relax_fmax) return crack_slab
<params> <LMTO_TBE_params n_types="2" control_file="ctrl.fe"> <per_type_data type="1" atomic_num="26"/> <per_type_data type="2" atomic_num="1"/> </LMTO_TBE_params> </params>""") #If there is an initial strain energy increment that here: pot.print_() screw_slab_unit.write('screw_unitcell.xyz') screw_slab_unit.set_calculator(pot) #Elastic constants are disabled until we have tight binding operational. if calc_elastic_constants and dyn_type != 'LOTF': cij = pot.get_elastic_constants(screw_slab_unit) print 'ELASTIC CONSTANTS' print ((cij / units.GPa).round(2)) E = youngs_modulus(cij, y) nu = poisson_ratio(cij, y, x) print 'Youngs Modulus: ', E/units.GPa,'Poisson Ratio: ', nu print 'Effective elastic modulus E: ', E/(1.-nu**2) print 'Loading Structure File:', '{0}.xyz'.format(input_file) defect = Atoms('{0}.xyz'.format(input_file)) top = defect.positions[:,1].max() bottom = defect.positions[:,1].min() left = defect.positions[:,0].min() right = defect.positions[:,0].max() orig_height = (defect.positions[:,1].max()-defect.positions[:,1].min()) #Attaching Properties to atoms object if calc_elastic_constants: defect.info['YoungsModulus'] = E
<params> <LMTO_TBE_params n_types="2" control_file="ctrl.fe"> <per_type_data type="1" atomic_num="26"/> <per_type_data type="2" atomic_num="1"/> </LMTO_TBE_params> </params>""") #If there is an initial strain energy increment that here: pot.print_() screw_slab_unit.write('screw_unitcell.xyz') screw_slab_unit.set_calculator(pot) #Elastic constants are disabled until we have tight binding operational. if calc_elastic_constants and dyn_type != 'LOTF': cij = pot.get_elastic_constants(screw_slab_unit) print 'ELASTIC CONSTANTS' print((cij / units.GPa).round(2)) E = youngs_modulus(cij, y) nu = poisson_ratio(cij, y, x) print 'Youngs Modulus: ', E / units.GPa, 'Poisson Ratio: ', nu print 'Effective elastic modulus E: ', E / (1. - nu**2) print 'Loading Structure File:', '{0}.xyz'.format(input_file) defect = Atoms('{0}.xyz'.format(input_file)) top = defect.positions[:, 1].max() bottom = defect.positions[:, 1].min() left = defect.positions[:, 0].min() right = defect.positions[:, 0].max() orig_height = (defect.positions[:, 1].max() - defect.positions[:, 1].min()) #Attaching Properties to atoms object if calc_elastic_constants: defect.info['YoungsModulus'] = E
a0 = si_bulk.cell[0, 0] print('Lattice constant %.3f A\n' % a0) # make a new bulk cell with correct a0 (so that off-diagonal lattice values are exactly zero) si_bulk = bulk('Si', 'diamond', a=a0, cubic=True) si_bulk.set_calculator(mm_pot) # ******* Find elastic constants ******* # Get 6x6 matrix of elastic constants C_ij c = mm_pot.get_elastic_constants(si_bulk) print('Elastic constants (GPa):') print((c / units.GPa).round(0)) print('') E = youngs_modulus(c, cleavage_plane) print('Young\'s modulus %.1f GPa' % (E / units.GPa)) nu = poisson_ratio(c, cleavage_plane, crack_direction) print('Poisson ratio % .3f\n' % nu) # **** Setup crack slab unit cell ****** print_crack_system(crack_direction, cleavage_plane, crack_front) # now, we build system aligned with requested crystallographic orientation unit_slab = Diamond(directions=[crack_direction, cleavage_plane, crack_front], size=(1, 1, 1), symbol='Si', pbc=True,
crack_seed_length = 40.0*units.Ang # Length of seed crack strain_ramp_length = 30.0*units.Ang # Distance over which strain is ramped up initial_G = 5.0*(units.J/units.m**2) # Initial energy flow to crack tip relax_fmax = 0.025*units.eV/units.Ang # Maximum force criteria for relaxation output_file = 'crack.xyz' # File to which structure will be written set_fortran_indexing(False) si_bulk = bulk('Si', 'diamond', a=5.431, cubic=True) mm_pot = Potential("IP SW") si_bulk.set_calculator(mm_pot) c = mm_pot.get_elastic_constants(si_bulk) E = youngs_modulus(c, cleavage_plane) nu = poisson_ratio(c, cleavage_plane, crack_direction) unit_slab = Diamond(directions=[crack_direction, cleavage_plane, crack_front], size=(1, 1, 1), symbol='Si', pbc=True, latticeconstant=5.431) 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())
def build_crack_cell(self, unit_slab, pot, fix_dist=1.0): """ Creates a CrackCell of the desired size and orientation with the top and bottom layer of atoms constrained. Returns: :class:`Atoms` - the relaxed crack_cell. """ self.nx = int(self.width / unit_slab.get_cell()[0, 0]) self.ny = int(self.height / unit_slab.get_cell()[1, 1]) if self.ny % 2 == 1: self.ny += 1 #self.ny = 1 print 'number of unit cells', self.nx, self.ny crack_slab = unit_slab * (self.nx, self.ny, self.nz) write('ref_slab.xyz', crack_slab) crack_slab.center(self.vacuum, axis=0) crack_slab.center(self.vacuum, axis=1) crack_slab.positions[:, 0] -= crack_slab.positions[:, 0].mean() crack_slab.positions[:, 1] -= crack_slab.positions[:, 1].mean() self.orig_width = (crack_slab.positions[:, 0].max() - crack_slab.positions[:, 0].min()) self.orig_height = (crack_slab.positions[:, 1].max() - crack_slab.positions[:, 1].min()) print(( 'Made slab with %d atoms, original width and height: %.1f x %.1f A^2' % (len(crack_slab), self.orig_width, self.orig_height))) top = crack_slab.positions[:, 1].max() bottom = crack_slab.positions[:, 1].min() left = crack_slab.positions[:, 0].min() right = crack_slab.positions[:, 0].max() #Constrain top and bottom layer of atoms: fixed_mask = ((abs(crack_slab.positions[:, 1] - top) < 1.0) | (abs(crack_slab.positions[:, 1] - bottom) < 1.0)) const = FixAtoms(mask=fixed_mask) crack_slab.set_constraint(const) #Strain is a dimensionless ratio we require elastic tensor #to translate the initial energy flow to the tip into a strain. self.E = youngs_modulus(self.cij, self.cleavage_plane) self.nu = poisson_ratio(self.cij, self.cleavage_plane, self.crack_direction) self.strain = G_to_strain(self.initial_G, self.E, self.nu, self.orig_height) seed = left + self.crack_seed_length tip = left + self.crack_seed_length + self.strain_ramp_length xpos = crack_slab.positions[:, 0] ypos = crack_slab.positions[:, 1] crack_slab.positions[:, 1] += thin_strip_displacement_y( xpos, ypos, self.strain, seed, tip) write('crack_slab_init.xyz', crack_slab) print('Applied initial load: strain=%.4f, G=%.2f J/m^2' % (self.strain, self.initial_G / (units.J / units.m**2))) pot_dir = os.environ['POTDIR'] crack_slab.set_calculator(pot) #Initial crack pos print 'crack_pos before relaxations' print find_crack_tip_stress_field(crack_slab, calc=mm_pot) print('Relaxing slab...') slab_opt = PreconFIRE(crack_slab) slab_opt.run(fmax=self.relax_fmax) return crack_slab