コード例 #1
0
ファイル: crack.py プロジェクト: Montmorency/fracture
  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
コード例 #2
0
 def check_if_cracked(atoms):
     orig_crack_pos = atoms.info['CrackPos'].copy()
     crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
     if not atoms.info['is_cracked'] and (crack_pos[0] -
                                          orig_crack_pos[0]) > tip_move_tol:
         atoms.info['is_cracked'] = True
         del atoms.constraints[atoms.constraints.index(strain_atoms)]
コード例 #3
0
 def update_qm_region_H(atoms):
   """
   Set quantum region around the Hydrogen. Also records crackpos.
   """
   mm_pot = Potential(mm_init_args,
                      param_filename = param_file,
                      cutoff_skin    = cutoff_skin)
 
   crack_pos    = find_crack_tip_stress_field(atoms, calc=mm_pot)
 #set quantum region to first hydrogen atom in list.
   h_pos        = atoms[h_list[0]].position 
   old_qm_list  = atoms.hybrid_vec.nonzero()[0]
   new_qm_list  = update_hysteretic_qm_region(atoms, old_qm_list, h_pos, 
                                              qm_inner_radius, 
                                              qm_outer_radius, 
                                              update_marks=False)
 #lets try setting the atoms object properties by hand?
   atoms.hybrid[:]               = 0
   atoms.hybrid[new_qm_list]     = 1
 #Distributed Force Mixing Properties:
   atoms.hybrid_vec[:]           = 0
   atoms.hybrid_vec[new_qm_list] = 1
   atoms.hybrid_1[:]             = atoms.hybrid_vec[:]
   atoms.params['core']          = h_pos
   atoms.params['CrackPos']      = crack_pos
   return
コード例 #4
0
    def printstatus():
        if (dynamics.nsteps % 10) == 0:
            print """
State      Time/fs    Temp/K     Strain      G/(J/m^2)  CrackPos/A D(CrackPos)/A 
---------------------------------------------------------------------------------"""
            log_format = (
                '%(label)-4s%(time)12.1f%(temperature)12.6f' +
                '%(strain)12.5f%(G)12.4f%(crack_pos_x)12.2f    (%(d_crack_pos_x)+5.2f)'
            )
            log_format2 = ('%(label)-4s%(time)12.1f%(temperature)12.6f')
            try:
                atoms.info[
                    'label'] = dynamics.state_label  # Label for the status line
            except AttributeError:
                atoms.info['label'] = 'classical'  # Label for the status line

            atoms.info['time'] = dynamics.get_time() / units.fs
            atoms.info['temperature'] = (atoms.get_kinetic_energy() /
                                         (1.5 * units.kB * len(atoms)))
            atoms.info['strain'] = get_strain(atoms)
            try:
                atoms.info['G'] = get_energy_release_rate(atoms) / (units.J /
                                                                    units.m**2)
            except:
                atoms.info['G'] = 0.0
            try:
                orig_crack_pos = atoms.info['CrackPos'].copy()
                crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
                atoms.info['crack_pos_x'] = crack_pos[0]
                atoms.info['d_crack_pos_x'] = crack_pos[0] - orig_crack_pos[0]
                print log_format % atoms.info
            except KeyError:
                print log_format2 % atoms.info
コード例 #5
0
  def printstatus():
    if (dynamics.nsteps%10)==0:
      print """
State      Time/fs    Temp/K     Strain      G/(J/m^2)  CrackPos/A D(CrackPos)/A 
---------------------------------------------------------------------------------"""
      log_format = ('%(label)-4s%(time)12.1f%(temperature)12.6f'+
                    '%(strain)12.5f%(G)12.4f%(crack_pos_x)12.2f    (%(d_crack_pos_x)+5.2f)')
      log_format2 = ('%(label)-4s%(time)12.1f%(temperature)12.6f')
      try:
        atoms.info['label'] = dynamics.state_label                # Label for the status line
      except AttributeError:
        atoms.info['label'] = 'classical'                # Label for the status line
        

      atoms.info['time']  = dynamics.get_time()/units.fs
      atoms.info['temperature'] = (atoms.get_kinetic_energy() /
                                   (1.5*units.kB*len(atoms)))
      atoms.info['strain'] = get_strain(atoms)
      try:
        atoms.info['G']      = get_energy_release_rate(atoms)/(units.J/units.m**2)
      except:
        atoms.info['G']      = 0.0
      try:
        orig_crack_pos = atoms.info['CrackPos'].copy()
        crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
        atoms.info['crack_pos_x']   = crack_pos[0]
        atoms.info['d_crack_pos_x'] = crack_pos[0] - orig_crack_pos[0]
        print log_format % atoms.info
      except KeyError:
        print log_format2 % atoms.info
コード例 #6
0
ファイル: run_crack_lotf_1.py プロジェクト: xielm12/QUIP
def check_if_cracked(atoms):
    crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)

    # stop straining if crack has advanced more than tip_move_tol
    if not atoms.info['is_cracked'] and (crack_pos[0] - orig_crack_pos[0]) > tip_move_tol:
        atoms.info['is_cracked'] = True
        del atoms.constraints[atoms.constraints.index(strain_atoms)]
コード例 #7
0
def printstatus():
    if dynamics.nsteps == 1:
        print """
State      Time/fs    Temp/K     Strain      G/(J/m^2)  CrackPos/A D(CrackPos)/A
---------------------------------------------------------------------------------"""

    log_format = (
        '%(label)-4s%(time)12.1f%(temperature)12.6f' +
        '%(strain)12.5f%(G)12.4f%(crack_pos_x)12.2f    (%(d_crack_pos_x)+5.2f)'
    )

    atoms.info['label'] = dynamics.state_label  # Label for the status line
    atoms.info['time'] = dynamics.get_time() / units.fs
    atoms.info['temperature'] = (atoms.get_kinetic_energy() /
                                 (1.5 * units.kB * len(atoms)))
    atoms.info['strain'] = get_strain(atoms)
    atoms.info['G'] = get_energy_release_rate(atoms) / (units.J / units.m**2)

    crack_pos = find_crack_tip_stress_field(atoms,
                                            calc=mm_pot,
                                            avg_sigma=avg_sigma)
    atoms.info['crack_pos_x'] = crack_pos[0]
    atoms.info['d_crack_pos_x'] = crack_pos[0] - orig_crack_pos[0]

    print log_format % atoms.info
コード例 #8
0
def check_if_cracked(atoms):
    crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)

    # stop straining if crack has advanced more than tip_move_tol
    if not atoms.info['is_cracked'] and (crack_pos[0] - orig_crack_pos[0]) > tip_move_tol:
        atoms.info['is_cracked'] = True
        del atoms.constraints[atoms.constraints.index(strain_atoms)]
コード例 #9
0
ファイル: run_crack_classical.py プロジェクト: yfyh2013/QUIP
def atom_straining(atoms):
    crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
    # keep straining until the crack tip has advanced to tip_move_tol
    if not atoms.info['is_cracked'] and (crack_pos[0] -
                                         orig_crack_pos[0]) < tip_move_tol:
        strain_atoms.apply_strain(atoms)
    elif not atoms.info['is_cracked']:
        atoms.info['is_cracked'] = True
コード例 #10
0
def update_qm_region(atoms):
    crack_pos = find_crack_tip_stress_field(atoms,
                                            calc=mm_pot,
                                            avg_sigma=avg_sigma)
    qm_list = qmmm_pot.get_qm_atoms(atoms)
    qm_list = update_hysteretic_qm_region(atoms, qm_list, crack_pos,
                                          qm_inner_radius, qm_outer_radius)
    qmmm_pot.set_qm_atoms(qm_list, atoms)
コード例 #11
0
  def update_qm_region(atoms):
    crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
    qm_list   = qmmm_pot.get_qm_atoms()
    qm_list   = update_hysteretic_qm_region(atoms, qm_list, crack_pos, qm_inner_radius, 
                                            qm_outer_radius, update_marks=True)
    qmmm_pot.set_qm_atoms(qm_list)
#lets try setting the atoms object properties by hand?
    atoms.hybrid[:] = HYBRID_NO_MARK
    atoms.hybrid[qm_list] = HYBRID_ACTIVE_MARK
コード例 #12
0
 def update_qm_region(atoms):
     crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
     qm_list = qmmm_pot.get_qm_atoms()
     qm_list = update_hysteretic_qm_region(atoms,
                                           qm_list,
                                           crack_pos,
                                           qm_inner_radius,
                                           qm_outer_radius,
                                           update_marks=True)
     qmmm_pot.set_qm_atoms(qm_list)
     #lets try setting the atoms object properties by hand?
     atoms.hybrid[:] = HYBRID_NO_MARK
     atoms.hybrid[qm_list] = HYBRID_ACTIVE_MARK
コード例 #13
0
def update_qm_region_crack(atoms):
  mm_pot = Potential(params.mm_init_args,
                     param_filename=params.param_file,
                     cutoff_skin=params.cutoff_skin)
  crack_pos    = find_crack_tip_stress_field(atoms, calc=mm_pot)
  old_qm_list  = atoms.hybrid_vec.nonzero()[0]
  new_qm_list  = update_hysteretic_qm_region(atoms, old_qm_list, crack_pos, 
                                             params.qm_inner_radius, 
                                             params.qm_outer_radius, 
                                             update_marks=False)
#lets try setting the atoms object properties by hand?
  atoms.hybrid[:] = 0
  atoms.hybrid[new_qm_list] = 1
#Distributed Force Mixing Properties:
  atoms.hybrid_vec[:] = 0
  atoms.hybrid_vec[new_qm_list] = 1
  atoms.hybrid_1[:] = atoms.hybrid_vec[:]
  atoms.params['core'] = crack_pos
  atoms.params['CrackPos'] = crack_pos
  return
コード例 #14
0
def printstatus():
    if dynamics.nsteps == 1:
        print """
State      Time/fs    Temp/K     Strain      G/(J/m^2)  CrackPos/A D(CrackPos)/A 
---------------------------------------------------------------------------------"""

    log_format = ('%(label)-4s%(time)12.1f%(temperature)12.6f'+
                  '%(strain)12.5f%(G)12.4f%(crack_pos_x)12.2f    (%(d_crack_pos_x)+5.2f)')

    atoms.info['label'] = 'D'                  # Label for the status line
    atoms.info['time'] = dynamics.get_time()/units.fs
    atoms.info['temperature'] = (atoms.get_kinetic_energy() /
                                 (1.5*units.kB*len(atoms)))
    atoms.info['strain'] = get_strain(atoms)
    atoms.info['G'] = get_energy_release_rate(atoms)/(units.J/units.m**2)
    
    crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
    atoms.info['crack_pos_x'] = crack_pos[0]
    atoms.info['d_crack_pos_x'] = crack_pos[0] - orig_crack_pos[0]

    print log_format % atoms.info
コード例 #15
0
ファイル: crack.py プロジェクト: Montmorency/fracture
 def write_crack_cell(self, crack_slab, mm_pot):
   print crack_slab.get_cell()
   crack_slab.info['nneightol']       = 1.30 # set nearest neighbour tolerance
   crack_slab.info['LatticeConstant'] = self.a0
   crack_slab.info['C11'] = self.cij[0, 0]
   crack_slab.info['C12'] = self.cij[0, 1]
   crack_slab.info['C44'] = self.cij[3, 3]
   crack_slab.info['YoungsModulus']   = self.E
   crack_slab.info['PoissonRatio_yx'] = self.nu
   crack_slab.info['G']               = self.initial_G
   crack_slab.info['OrigWidth']       = self.orig_width
   crack_slab.info['OrigHeight']      = self.orig_height
   crack_slab.info['CrackDirection']  = self.crack_direction
   crack_slab.info['CleavagePlane']   = self.cleavage_plane
   crack_slab.info['CrackFront']      = self.crack_front
   crack_slab.info['strain']          = self.strain
   #Initial guess for crack_pos
   crack_slab.info['CrackPos']        = np.array([1.5, 1.5, 1.5])
   crack_pos = find_crack_tip_stress_field(crack_slab, calc=mm_pot)
   print 'Found crack tip at position %s' % crack_pos
   crack_slab.info['CrackPos']        = crack_pos
   crack_slab.info['is_cracked']      = False
   write('crack.xyz', crack_slab)
コード例 #16
0
 def write_crack_cell(self, crack_slab, mm_pot):
     print crack_slab.get_cell()
     crack_slab.info['nneightol'] = 1.30  # set nearest neighbour tolerance
     crack_slab.info['LatticeConstant'] = self.a0
     crack_slab.info['C11'] = self.cij[0, 0]
     crack_slab.info['C12'] = self.cij[0, 1]
     crack_slab.info['C44'] = self.cij[3, 3]
     crack_slab.info['YoungsModulus'] = self.E
     crack_slab.info['PoissonRatio_yx'] = self.nu
     crack_slab.info['G'] = self.initial_G
     crack_slab.info['OrigWidth'] = self.orig_width
     crack_slab.info['OrigHeight'] = self.orig_height
     crack_slab.info['CrackDirection'] = self.crack_direction
     crack_slab.info['CleavagePlane'] = self.cleavage_plane
     crack_slab.info['CrackFront'] = self.crack_front
     crack_slab.info['strain'] = self.strain
     #Initial guess for crack_pos
     crack_slab.info['CrackPos'] = np.array([1.5, 1.5, 1.5])
     crack_pos = find_crack_tip_stress_field(crack_slab, calc=mm_pot)
     print 'Found crack tip at position %s' % crack_pos
     crack_slab.info['CrackPos'] = crack_pos
     crack_slab.info['is_cracked'] = False
     write('crack.xyz', crack_slab)
コード例 #17
0
 def check_if_cracked(atoms):
   orig_crack_pos = atoms.info['CrackPos'].copy()
   crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
   if not atoms.info['is_cracked'] and (crack_pos[0] - orig_crack_pos[0]) > tip_move_tol:
     atoms.info['is_cracked'] = True
     del atoms.constraints[atoms.constraints.index(strain_atoms)]
コード例 #18
0
ファイル: make_crack.py プロジェクト: Ben-Vosper/Silicon
                                 crack_slab.positions[:, 0],
                                 crack_slab.positions[:, 1],
                                 strain,
                                 left + crack_seed_length,
                                 left + crack_seed_length + strain_ramp_length)

print('Applied initial load: strain=%.4f, G=%.2f J/m^2' %
      (strain, initial_G / (units.J / units.m**2)))


crack_slab.set_calculator(mm_pot)
minim = Minim(crack_slab, relax_positions=True, relax_cell=False)
minim.run(fmax=relax_fmax)

# Find initial position of crack tip
crack_pos = find_crack_tip_stress_field(crack_slab, calc=mm_pot)
print 'Found crack tip at position %s' % crack_pos

# Save all calculated materials properties inside the Atoms object
crack_slab.info['nneightol'] = 1.3 # nearest neighbour tolerance
crack_slab.info['LatticeConstant'] = 5.431
crack_slab.info['C11'] = c[0, 0]
crack_slab.info['C12'] = c[0, 1]
crack_slab.info['C44'] = c[3, 3]
crack_slab.info['YoungsModulus'] = E
crack_slab.info['PoissonRatio_yx'] = nu
crack_slab.info['SurfaceEnergy'] = gamma
crack_slab.info['OrigWidth'] = orig_width
crack_slab.info['OrigHeight'] = orig_height
crack_slab.info['CrackDirection'] = crack_direction
crack_slab.info['CleavagePlane'] = cleavage_plane
コード例 #19
0
    crack_slab.positions[:, 0], crack_slab.positions[:, 1], strain,
    left + crack_seed_length, left + crack_seed_length + strain_ramp_length)

print('Applied initial load: strain=%.4f, G=%.2f J/m^2' %
      (strain, initial_G / (units.J / units.m**2)))

# ***** Relaxation of crack slab  *****

# optionally, relax the slab, keeping top and bottom rows fixed
print('Relaxing slab...')
crack_slab.set_calculator(mm_pot)
minim = Minim(crack_slab, relax_positions=True, relax_cell=False)
minim.run(fmax=0.01)

# Find initial position of crack tip
crack_pos = find_crack_tip_stress_field(crack_slab, calc=mm_pot)
crack_pos = find_crack_tip_coordination(crack_slab,
                                        edge_tol=10.0,
                                        strip_height=30.0,
                                        nneightol=1.3)
print 'Found crack tip at position %s' % crack_pos

# Save all calculated materials properties inside the Atoms object

crack_slab.info['CrackPos'] = crack_pos
crack_slab.info['is_cracked'] = False

# ******** Save output file **********

# save results in extended XYZ format, including extra properties and info
print('Writing crack slab to file %s' % output_file)
コード例 #20
0
ファイル: run_crack.py プロジェクト: Montmorency/fracture
        pred_corr_logfile.close()
  else:
    mm_pot = Potential(mm_init_args, param_filename=pot_file, cutoff_skin=cutoff_skin)
    atoms = AtomsReader(args.input_file)[-1]
    atoms.set_calculator(mm_pot)
    if args.restart:
#delete certain keys so they don't cause problem in write_xyz.
        del_keys = ['force','forces', 'forces0']
        array_keys = atoms.arrays.keys()
        prop_keys = atoms.properties.keys()
        for key in del_keys:
            if key in array_keys:
                del(atoms.arrays[key])

    strain_atoms = fix_edges(atoms)
    current_crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
    print 'Current Crack Position: ', current_crack_pos
    if not args.restart: 
      print 'Thermalizing Atoms'
      MaxwellBoltzmannDistribution(atoms, 2.0*sim_T)

    dynamics = VelocityVerlet(atoms, timestep)

    def print_context(ats=atoms, dyn=dynamics):
        print 'steps, T', dyn.nsteps, ats.get_kinetic_energy()/(1.5*units.kB*len(ats))
        print 'G', get_energy_release_rate(ats)/(units.J/units.m**2)
        print 'strain', get_strain(ats)

    #for 0.25 fs time step we have an image every half 
    #phonon cycle which is plenty
    dynamics.attach(print_context, interval=32)
コード例 #21
0
ファイル: run_crack.py プロジェクト: Montmorency/fracture
 def update_qm_region(atoms):
     crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot, avg_sigma=avg_sigma)
     qm_list   = qmmm_pot.get_qm_atoms(atoms)
     qm_list   = update_hysteretic_qm_region(atoms, qm_list, crack_pos,
                                             qm_inner_radius, qm_outer_radius)
     qmmm_pot.set_qm_atoms(qm_list, atoms)
コード例 #22
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