Beispiel #1
0
oldr = a[0].position.copy()
a.center(vacuum=params.vacuum, axis=0)
a.center(vacuum=params.vacuum, axis=1)
tip_x0 += a[0].position[0] - oldr[0]
tip_y0 += a[0].position[1] - oldr[1]
cryst.set_cell(a.cell)
cryst.translate(a[0].position - oldr)

g = a.get_array('groups')
mask = g != 0

# Choose which bond to break.
bondlength = param('bondlength', 1.85)
bond1, bond2 = param('bond',
                     crack.find_tip_coordination(a, bondlength=bondlength))

logger.pr('Opening bond {0}--{1}, initial bond length {2}' \
          .format(bond1, bond2, a.get_distance(bond1, bond2, mic=True)))

# centre vertically on the opening bond
a.translate([
    0.,
    a.cell[1, 1] / 2.0 - (a.positions[bond1, 1] + a.positions[bond2, 1]) / 2.0,
    0
])

tip_x0 = (a.positions[bond1, 0] + a.positions[bond2, 0]) / 2
tip_y0 = (a.positions[bond1, 1] + a.positions[bond2, 1]) / 2

b = a.copy()
tip_y += a[0].position[1] - oldr[1]
cryst.set_cell(a.cell)
cryst.translate(a[0].position - oldr)
ase.io.write('notch.xyz', a, format='extxyz')

parprint('Initial tip position {0} {1}'.format(tip_x, tip_y))

# Groups mark the fixed region and the region use for fitting the crack tip.
g = a.get_array('groups')

# Assign calculator.
a.set_calculator(params.calc)

for j in range(params.n_bonds):

    bond1, bond2 = crack.find_tip_coordination(a)
    print 'Breaking tip bond {0}--{1}'.format(bond1, bond2)

    # Run crack calculation.
    for i, bond_length in enumerate(params.bond_lengths):
        parprint('=== bond_length = {0} ==='.format(bond_length))
        xyz_file = 'bond_%d_%4d.xyz' % (j+1, int(bond_length*1000))
        if os.path.exists(xyz_file):
            parprint('%s found, skipping' % xyz_file)
            a = ase.io.read(xyz_file)
            del a[np.logical_or(a.numbers == atomic_numbers[ACTUAL_CRACK_TIP],
                                a.numbers == atomic_numbers[FITTED_CRACK_TIP])]
            a.set_calculator(params.calc)
        else:
            a.set_constraint(None)
            a.set_distance(bond1, bond2, bond_length)
Beispiel #3
0
                           tip_x, tip_y, params.k1*k1g)
a.positions[:ncryst,0] += ux
a.positions[:ncryst,1] += uy

basename = parameter('basename', 'energy_barrier')

# Center notched configuration in simulation cell and ensure enough vacuum.
oldr = a[0].position.copy()
a.center(vacuum=params.vacuum, axis=0)
a.center(vacuum=params.vacuum, axis=1)
tip_x += a[0].position[0] - oldr[0]
tip_y += a[0].position[1] - oldr[1]

# Choose which bond to break.
bond1, bond2 = parameter('bond',
                         crack.find_tip_coordination(a, bondlength=bondlength))

# Hydrogenate?
if parameter('hydrogenate', False):
    # Get surface atoms of cluster with crack
    coord = np.bincount(neighbour_list('i', a, bondlength), minlength=len(a))
    # Exclude all atoms of the crack face from hydrogenation
    exclude = np.logical_and(a.get_array('groups')==1, coord!=4)
    a.set_array('coord', coord)
    a.set_array('exclude', exclude)
    a = hydrogenate(cryst, bondlength, parameter('XH_bondlength'), b=a,
                    exclude=exclude)
    g = a.get_array('groups')
    g[np.array(a.get_chemical_symbols())=='H'] = -1
    a.set_array('groups', g)
    ase.io.write('{0}_hydrogenated.cfg'.format(basename), a)
Beispiel #4
0
def setup_crack(logger=screen):
    calc = parameter('calc')

    cryst = parameter('cryst').copy()
    cryst.set_pbc(True)

    # Double check elastic constants. We're just assuming this is really a periodic
    # system. (True if it comes out of the cluster routines.)

    compute_elastic_constants = parameter('compute_elastic_constants', False)
    elastic_fmax = parameter('elastic_fmax', 0.01)
    elastic_symmetry = parameter('elastic_symmetry', 'triclinic')
    elastic_optimizer = parameter('elastic_optimizer', ase.optimize.FIRE)

    if compute_elastic_constants:
        cryst.set_calculator(calc)
        log_file = open('elastic_constants.log', 'w')
        C, C_err = fit_elastic_constants(cryst,
                                         verbose=False,
                                         symmetry=elastic_symmetry,
                                         optimizer=elastic_optimizer,
                                         logfile=log_file,
                                         fmax=elastic_fmax)
        log_file.close()
        logger.pr('Measured elastic constants (in GPa):')
        logger.pr(np.round(C * 10 / GPa) / 10)

        crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                      parameter('crack_front'),
                                      Crot=C / GPa)
    else:
        if has_parameter('C'):
            crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                          parameter('crack_front'),
                                          C=parameter('C'))
        else:
            crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                          parameter('crack_front'),
                                          parameter('C11'), parameter('C12'),
                                          parameter('C44'))

    logger.pr('Elastic constants used for boundary condition (in GPa):')
    logger.pr(np.round(crk.C * 10) / 10)

    # Get Griffith's k1.
    k1g = crk.k1g(parameter('surface_energy'))
    logger.pr('Griffith k1 = %f' % k1g)

    # Apply initial strain field.
    tip_x = parameter('tip_x', cryst.cell.diagonal()[0] / 2)
    tip_y = parameter('tip_y', cryst.cell.diagonal()[1] / 2)

    bondlength = parameter('bondlength', 2.7)
    bulk_nn = parameter('bulk_nn', 4)

    a = cryst.copy()
    a.set_pbc([False, False, True])

    hydrogenate_flag = parameter('hydrogenate', False)
    hydrogenate_crack_face_flag = parameter('hydrogenate_crack_face', True)

    if hydrogenate_flag and not hydrogenate_crack_face_flag:
        # Get surface atoms of cluster with crack
        a = hydrogenate(cryst, bondlength, parameter('XH_bondlength'), b=a)
        g = a.get_array('groups')
        g[a.numbers == 1] = -1
        a.set_array('groups', g)
        cryst = a.copy()

    k1 = parameter('k1')
    try:
        k1 = k1[0]
    except:
        pass
    ux, uy = crk.displacements(cryst.positions[:, 0], cryst.positions[:, 1],
                               tip_x, tip_y, k1 * k1g)
    a.positions[:len(cryst), 0] += ux
    a.positions[:len(cryst), 1] += uy

    # Center notched configuration in simulation cell and ensure enough vacuum.
    oldr = a[0].position.copy()
    vacuum = parameter('vacuum')
    a.center(vacuum=vacuum, axis=0)
    a.center(vacuum=vacuum, axis=1)
    tip_x += a[0].x - oldr[0]
    tip_y += a[0].y - oldr[1]

    # Choose which bond to break.
    bond1, bond2 = \
        parameter('bond', crack.find_tip_coordination(a, bondlength=bondlength, bulk_nn=bulk_nn))

    if parameter('center_crack_tip_on_bond', False):
        tip_x, tip_y, dummy = (a.positions[bond1] + a.positions[bond2]) / 2

    # Hydrogenate?
    coord = np.bincount(neighbour_list('i', a, bondlength), minlength=len(a))
    a.set_array('coord', coord)

    if parameter('optimize_full_crack_face', False):
        g = a.get_array('groups')
        gcryst = cryst.get_array('groups')
        coord = a.get_array('coord')
        g[coord != 4] = -1
        gcryst[coord != 4] = -1
        a.set_array('groups', g)
        cryst.set_array('groups', gcryst)

    if hydrogenate_flag and hydrogenate_crack_face_flag:
        # Get surface atoms of cluster with crack
        exclude = np.logical_and(a.get_array('groups') == 1, coord != 4)
        a.set_array('exclude', exclude)
        a = hydrogenate(cryst,
                        bondlength,
                        parameter('XH_bondlength'),
                        b=a,
                        exclude=exclude)
        g = a.get_array('groups')
        g[a.numbers == 1] = -1
        a.set_array('groups', g)
        basename = parameter('basename', 'energy_barrier')
        ase.io.write('{0}_hydrogenated.xyz'.format(basename),
                     a,
                     format='extxyz')

    # Move reference crystal by same amount
    cryst.set_cell(a.cell)
    cryst.set_pbc([False, False, True])
    cryst.translate(a[0].position - oldr)

    # Groups mark the fixed region and the region use for fitting the crack tip.
    g = a.get_array('groups')
    gcryst = cryst.get_array('groups')

    logger.pr('Opening bond {0}--{1}, initial bond length {2}'.format(
        bond1, bond2, a.get_distance(bond1, bond2, mic=True)))

    # centre vertically on the opening bond
    if parameter('center_cell_on_bond', True):
        a.translate([
            0., a.cell[1, 1] / 2.0 -
            (a.positions[bond1, 1] + a.positions[bond2, 1]) / 2.0, 0.
        ])

    a.info['bond1'] = bond1
    a.info['bond2'] = bond2

    return a, cryst, crk, k1g, tip_x, tip_y, bond1, bond2, g == 0, gcryst == 0, g == 1
Beispiel #5
0
        def test_embedding_size_convergence(self):
            calc = Tersoff(**Tersoff_PRB_39_5566_Si_C)

            el = 'C'
            a0 = 3.566
            surface_energy = 2.7326 * 10
            crack_surface = [1, 1, 1]
            crack_front = [1, -1, 0]
            skin_x, skin_y = 1, 1

            cryst = bulk(el, cubic=True)
            cryst.set_calculator(calc)
            FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
            a0 = cryst.cell.diagonal().mean()
            bondlength = cryst.get_distance(0, 1)
            #print('a0 =', a0, ', bondlength =', bondlength)

            cryst = diamond(el, a0, [1, 1, 1], crack_surface, crack_front)
            cryst.set_pbc(True)
            cryst.set_calculator(calc)
            cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

            C, C_err = fit_elastic_constants(cryst,
                                             verbose=False,
                                             symmetry='cubic',
                                             optimizer=FIRE,
                                             fmax=1e-6)
            #print('Measured elastic constants (in GPa):')
            #print(np.round(C*10/units.GPa)/10)

            bondlengths = []
            refcell = None
            reftip_x = None
            reftip_y = None
            #[41, 39, 1],
            for i, n in enumerate([[21, 19, 1], [11, 9, 1], [6, 5, 1]]):
                #print(n)
                cryst = diamond(el, a0, n, crack_surface, crack_front)
                set_groups(cryst, n, skin_x, skin_y)
                cryst.set_pbc(True)
                cryst.set_calculator(calc)
                FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
                cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

                ase.io.write('cryst_{}.xyz'.format(i), cryst, format='extxyz')

                crk = crack.CubicCrystalCrack(crack_surface,
                                              crack_front,
                                              Crot=C / units.GPa)
                k1g = crk.k1g(surface_energy)

                tip_x = cryst.cell.diagonal()[0] / 2
                tip_y = cryst.cell.diagonal()[1] / 2

                a = cryst.copy()
                a.set_pbc([False, False, True])

                k1 = 1.0
                ux, uy = crk.displacements(cryst.positions[:, 0],
                                           cryst.positions[:, 1], tip_x, tip_y,
                                           k1 * k1g)

                a.positions[:, 0] += ux
                a.positions[:, 1] += uy

                # Center notched configuration in simulation cell and ensure enough vacuum.
                oldr = a[0].position.copy()
                if refcell is None:
                    a.center(vacuum=10.0, axis=0)
                    a.center(vacuum=10.0, axis=1)
                    refcell = a.cell.copy()
                    tip_x += a[0].x - oldr[0]
                    tip_y += a[0].y - oldr[1]
                    reftip_x = tip_x
                    reftip_y = tip_y
                else:
                    a.set_cell(refcell)

                # Shift tip position so all systems are exactly centered at the same spot
                a.positions[:, 0] += reftip_x - tip_x
                a.positions[:, 1] += reftip_y - tip_y

                refpositions = a.positions.copy()

                # Move reference crystal by same amount
                cryst.set_cell(a.cell)
                cryst.set_pbc([False, False, True])
                cryst.translate(a[0].position - oldr)

                bond1, bond2 = crack.find_tip_coordination(
                    a, bondlength=bondlength * 1.2)

                # Groups mark the fixed region and the region use for fitting the crack tip.
                g = a.get_array('groups')
                gcryst = cryst.get_array('groups')

                ase.io.write('cryst_{}.xyz'.format(i), cryst)

                a.set_calculator(calc)
                a.set_constraint(FixAtoms(mask=g == 0))
                FIRE(a, logfile=None).run(fmax=1e-6)

                dpos = np.sqrt((
                    (a.positions[:, 0] - refpositions[:, 0]) / ux)**2 + (
                        (a.positions[:, 1] - refpositions[:, 1]) / uy)**2)
                a.set_array('dpos', dpos)

                distance_from_tip = np.sqrt((a.positions[:, 0] - reftip_x)**2 +
                                            (a.positions[:, 1] - reftip_y)**2)

                ase.io.write('crack_{}.xyz'.format(i), a)

                # Compute average bond length per atom
                neighi, neighj, neighd = neighbour_list('ijd',
                                                        a,
                                                        cutoff=bondlength *
                                                        1.2)
                coord = np.bincount(neighi)
                assert coord.max() == 4

                np.savetxt(
                    'dpos_{}.out'.format(i),
                    np.transpose(
                        [distance_from_tip[coord == 4], dpos[coord == 4]]))

                # Compute distances from tipcenter
                neighdist = np.sqrt((
                    (a.positions[neighi, 0] + a.positions[neighj, 0]) / 2 -
                    reftip_x)**2 + (
                        (a.positions[neighi, 1] + a.positions[neighj, 1]) / 2 -
                        reftip_y)**2)

                np.savetxt('bl_{}.out'.format(i),
                           np.transpose([neighdist, neighd]))

                bondlengths += [a.get_distance(bond1, bond2)]
            print(bondlengths, np.diff(bondlengths),
                  bondlengths / bondlengths[-1] - 1)
            assert np.all(np.diff(bondlengths) > 0)
            assert np.max(bondlengths / bondlengths[0] - 1) < 0.01
Beispiel #6
0
        def test_embedding_size_convergence(self):
            calc = Tersoff(**Tersoff_PRB_39_5566_Si_C)

            el = 'C'
            a0 = 3.566
            surface_energy = 2.7326 * 10
            crack_surface = [1, 1, 1]
            crack_front = [1, -1, 0]
            skin_x, skin_y = 1, 1

            cryst = bulk(el, cubic=True)
            cryst.set_calculator(calc)
            FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
            a0 = cryst.cell.diagonal().mean()
            bondlength = cryst.get_distance(0, 1)
            #print('a0 =', a0, ', bondlength =', bondlength)

            cryst = diamond(el, a0, [1,1,1], crack_surface, crack_front)
            cryst.set_pbc(True)
            cryst.set_calculator(calc)
            cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

            C, C_err = fit_elastic_constants(cryst, verbose=False,
                                             symmetry='cubic',
                                             optimizer=FIRE,
                                             fmax=1e-6)
            #print('Measured elastic constants (in GPa):')
            #print(np.round(C*10/units.GPa)/10)

            bondlengths = []
            refcell = None
            reftip_x = None
            reftip_y = None
            #[41, 39, 1], 
            for i, n in enumerate([[21, 19, 1], [11, 9, 1], [6, 5, 1]]):
                #print(n)
                cryst = diamond(el, a0, n, crack_surface, crack_front)
                set_groups(cryst, n, skin_x, skin_y)
                cryst.set_pbc(True)
                cryst.set_calculator(calc)
                FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
                cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

                ase.io.write('cryst_{}.xyz'.format(i), cryst, format='extxyz')

                crk = crack.CubicCrystalCrack(crack_surface,
                                              crack_front,
                                              Crot=C/units.GPa)
                k1g = crk.k1g(surface_energy)

                tip_x = cryst.cell.diagonal()[0]/2
                tip_y = cryst.cell.diagonal()[1]/2

                a = cryst.copy()
                a.set_pbc([False, False, True])

                k1 = 1.0
                ux, uy = crk.displacements(cryst.positions[:,0], cryst.positions[:,1],
                                           tip_x, tip_y, k1*k1g)

                a.positions[:, 0] += ux
                a.positions[:, 1] += uy

                # Center notched configuration in simulation cell and ensure enough vacuum.
                oldr = a[0].position.copy()
                if refcell is None:
                    a.center(vacuum=10.0, axis=0)
                    a.center(vacuum=10.0, axis=1)
                    refcell = a.cell.copy()
                    tip_x += a[0].x - oldr[0]
                    tip_y += a[0].y - oldr[1]
                    reftip_x = tip_x
                    reftip_y = tip_y
                else:
                    a.set_cell(refcell)

                # Shift tip position so all systems are exactly centered at the same spot
                a.positions[:, 0] += reftip_x - tip_x
                a.positions[:, 1] += reftip_y - tip_y

                refpositions = a.positions.copy()

                # Move reference crystal by same amount
                cryst.set_cell(a.cell)
                cryst.set_pbc([False, False, True])
                cryst.translate(a[0].position - oldr)

                bond1, bond2 = crack.find_tip_coordination(a, bondlength=bondlength*1.2)

                # Groups mark the fixed region and the region use for fitting the crack tip.
                g = a.get_array('groups')
                gcryst = cryst.get_array('groups')

                ase.io.write('cryst_{}.xyz'.format(i), cryst)

                a.set_calculator(calc)
                a.set_constraint(FixAtoms(mask=g==0))
                FIRE(a, logfile=None).run(fmax=1e-6)

                dpos = np.sqrt(((a.positions[:, 0]-refpositions[:, 0])/ux)**2 + ((a.positions[:, 1]-refpositions[:, 1])/uy)**2)
                a.set_array('dpos', dpos)

                distance_from_tip = np.sqrt((a.positions[:, 0]-reftip_x)**2 + (a.positions[:, 1]-reftip_y)**2)

                ase.io.write('crack_{}.xyz'.format(i), a)

                # Compute average bond length per atom
                neighi, neighj, neighd = neighbour_list('ijd', a, cutoff=bondlength*1.2)
                coord = np.bincount(neighi)
                assert coord.max() == 4

                np.savetxt('dpos_{}.out'.format(i), np.transpose([distance_from_tip[coord==4], dpos[coord==4]]))

                # Compute distances from tipcenter
                neighdist = np.sqrt(((a.positions[neighi,0]+a.positions[neighj,0])/2-reftip_x)**2 +
                                    ((a.positions[neighi,1]+a.positions[neighj,1])/2-reftip_y)**2)

                np.savetxt('bl_{}.out'.format(i), np.transpose([neighdist, neighd]))

                bondlengths += [a.get_distance(bond1, bond2)]
            print(bondlengths, np.diff(bondlengths), bondlengths/bondlengths[-1]-1)
            assert np.all(np.diff(bondlengths) > 0)
            assert np.max(bondlengths/bondlengths[0]-1) < 0.01
Beispiel #7
0
def setup_crack(logger=screen):
    calc = parameter('calc')

    cryst = parameter('cryst').copy()
    cryst.set_pbc(True)

    # Double check elastic constants. We're just assuming this is really a periodic
    # system. (True if it comes out of the cluster routines.)

    compute_elastic_constants = parameter('compute_elastic_constants', False)
    elastic_fmax = parameter('elastic_fmax', 0.01)
    elastic_symmetry = parameter('elastic_symmetry', 'triclinic')
    elastic_optimizer = parameter('elastic_optimizer', ase.optimize.FIRE)

    if compute_elastic_constants:
        cryst.set_calculator(calc)
        log_file = open('elastic_constants.log', 'w')
        C, C_err = fit_elastic_constants(cryst, verbose=False,
                                         symmetry=elastic_symmetry,
                                         optimizer=elastic_optimizer,
                                         logfile=log_file,
                                         fmax=elastic_fmax)
        log_file.close()
        logger.pr('Measured elastic constants (in GPa):')
        logger.pr(np.round(C*10/GPa)/10)

        crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                      parameter('crack_front'),
                                      Crot=C/GPa)
    else:
        if has_parameter('C'):
            crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                          parameter('crack_front'),
                                          C=parameter('C'))
        else:
            crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                          parameter('crack_front'),
                                          parameter('C11'), parameter('C12'),
                                          parameter('C44'))


    logger.pr('Elastic constants used for boundary condition (in GPa):')
    logger.pr(np.round(crk.C*10)/10)

    # Get Griffith's k1.
    k1g = crk.k1g(parameter('surface_energy'))
    logger.pr('Griffith k1 = %f' % k1g)

    # Apply initial strain field.
    tip_x = parameter('tip_x', cryst.cell.diagonal()[0]/2)
    tip_y = parameter('tip_y', cryst.cell.diagonal()[1]/2)

    bondlength = parameter('bondlength', 2.7)
    bulk_nn = parameter('bulk_nn', 4)

    a = cryst.copy()
    a.set_pbc([False, False, True])

    hydrogenate_flag = parameter('hydrogenate', False)
    hydrogenate_crack_face_flag = parameter('hydrogenate_crack_face', True)

    if hydrogenate_flag and not hydrogenate_crack_face_flag:
        # Get surface atoms of cluster with crack
        a = hydrogenate(cryst, bondlength, parameter('XH_bondlength'), b=a)
        g = a.get_array('groups')
        g[a.numbers==1] = -1
        a.set_array('groups', g)
        cryst = a.copy()

    k1 = parameter('k1')
    try:
      k1 = k1[0]
    except:
      pass
    ux, uy = crk.displacements(cryst.positions[:,0], cryst.positions[:,1],
                               tip_x, tip_y, k1*k1g)
    a.positions[:len(cryst),0] += ux
    a.positions[:len(cryst),1] += uy

    # Center notched configuration in simulation cell and ensure enough vacuum.
    oldr = a[0].position.copy()
    vacuum = parameter('vacuum')
    a.center(vacuum=vacuum, axis=0)
    a.center(vacuum=vacuum, axis=1)
    tip_x += a[0].x - oldr[0]
    tip_y += a[0].y - oldr[1]

    # Choose which bond to break.
    bond1, bond2 = \
        parameter('bond', crack.find_tip_coordination(a, bondlength=bondlength, bulk_nn=bulk_nn))

    if parameter('center_crack_tip_on_bond', False):
        tip_x, tip_y, dummy = (a.positions[bond1]+a.positions[bond2])/2

    # Hydrogenate?
    coord = np.bincount(neighbour_list('i', a, bondlength), minlength=len(a))
    a.set_array('coord', coord)

    if parameter('optimize_full_crack_face', False):
        g = a.get_array('groups')
        gcryst = cryst.get_array('groups')
        coord = a.get_array('coord')
        g[coord!=4] = -1
        gcryst[coord!=4] = -1
        a.set_array('groups', g)
        cryst.set_array('groups', gcryst)

    if hydrogenate_flag and hydrogenate_crack_face_flag:
        # Get surface atoms of cluster with crack
        exclude = np.logical_and(a.get_array('groups')==1, coord!=4)
        a.set_array('exclude', exclude)
        a = hydrogenate(cryst, bondlength, parameter('XH_bondlength'), b=a,
                        exclude=exclude)
        g = a.get_array('groups')
        g[a.numbers==1] = -1
        a.set_array('groups', g)
        basename = parameter('basename', 'energy_barrier')
        ase.io.write('{0}_hydrogenated.xyz'.format(basename), a,
                     format='extxyz')

    # Move reference crystal by same amount
    cryst.set_cell(a.cell)
    cryst.set_pbc([False, False, True])
    cryst.translate(a[0].position - oldr)

    # Groups mark the fixed region and the region use for fitting the crack tip.
    g = a.get_array('groups')
    gcryst = cryst.get_array('groups')

    logger.pr('Opening bond {0}--{1}, initial bond length {2}'.
          format(bond1, bond2, a.get_distance(bond1, bond2, mic=True)))

    # centre vertically on the opening bond
    if parameter('center_cell_on_bond', True):
      a.translate([0., a.cell[1,1]/2.0 -
                      (a.positions[bond1, 1] +
                       a.positions[bond2, 1])/2.0, 0.])

    a.info['bond1'] = bond1
    a.info['bond2'] = bond2

    return a, cryst, crk, k1g, tip_x, tip_y, bond1, bond2, g==0, gcryst==0, g==1
Beispiel #8
0
a.positions[:,1] += uy

oldr = a[0].position.copy()
a.center(vacuum=params.vacuum, axis=0)
a.center(vacuum=params.vacuum, axis=1)
tip_x0 += a[0].position[0] - oldr[0]
tip_y0 += a[0].position[1] - oldr[1]
cryst.set_cell(a.cell)
cryst.translate(a[0].position - oldr)

g = a.get_array('groups')
mask = g!=0

# Choose which bond to break.
bondlength = param('bondlength', 1.85)
bond1, bond2 = param('bond', crack.find_tip_coordination(a, bondlength=bondlength))

logger.pr('Opening bond {0}--{1}, initial bond length {2}' \
          .format(bond1, bond2, a.get_distance(bond1, bond2, mic=True)))

# centre vertically on the opening bond
a.translate([0., a.cell[1,1]/2.0 - 
                (a.positions[bond1, 1] + 
                 a.positions[bond2, 1])/2.0, 0])

tip_x0 = (a.positions[bond1, 0] + a.positions[bond2, 0])/2
tip_y0 = (a.positions[bond1, 1] + a.positions[bond2, 1])/2

b = a.copy()
b += ase.Atom('H', (tip_x0, tip_y0, b.cell[2, 2]/2))
ase.io.write('notch.xyz', b, format='extxyz')