Exemple #1
0
  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
Exemple #2
0
    <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
Exemple #3
0
    <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
Exemple #4
0
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,
Exemple #5
0
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())
Exemple #6
0
    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