Beispiel #1
0
def build_GB(unit_GB_up, unit_GB_down, tx, tz):
    ny = int(ceil(height / unit_GB_up.cell[1, 1]))
    # print ny
    ny2 = ny * 2.
    GB_up = supercell(unit_GB_up, 2, ny2, 6)
    GB_up = GB_up.select(GB_up.positions[:, 1] >= GB_up.positions[:, 1].mean())
    print "created %d atoms in up grain" % (len(GB_up))
    GB_down = supercell(unit_GB_down, 2, ny2, 6)
    GB_down = GB_down.select(
        GB_down.positions[:, 1] <= ny * unit_GB_down.cell[1, 1])
    print "created %d atoms in down grain" % (len(GB_down))
    # GB_up.positions[:,1]+= GB_up.positions[:, 1].max()
    GB_down.positions[:, 0] += tx
    GB_down.positions[:, 2] += tz
    GB = GB_down + GB_up
    # GB.set_cell([GB_down.cell[0],GB_down.cell[1]*2,GB_down.cell[2]])
    return GB
Beispiel #2
0
def makecrack_main(params, stem):
    """Given a CrackParams object `param`, construct and return a new crack slab Atoms object."""

    xmlfilename = stem+'.xml'

    print_title('Initialisation')

    verbosity_push(params.io_verbosity)
    params.print_()

    print("Initialising classical potential with args " + params.classical_args.strip() +
          " from file " + xmlfilename)
    classicalpot = Potential(params.classical_args, param_filename=xmlfilename)
    classicalpot.print_()

    mpi_glob = MPI_context()

    crack_slab, width, height, E, v, v2, bulk = crack_make_slab(params, classicalpot)
    if params.crack_free_surfaces:
       depth = crack_slab.pos[3,:].max() - crack_slab.pos[3,:].min()
    else:
       depth = crack_slab.lattice[3,3]

    # Save bulk cube (used for qm_rescale_r parameter in crack code)
    if params.qm_args.startswith('TB'):
        bigger_bulk = supercell(bulk, 2, 2, 2)
        bulk = bigger_bulk
    bulk.write(stem+'_bulk.xyz')

    crack_slab.write(stem+'_slab.xyz')

    crack_slab.params['OrigWidth'] = width
    crack_slab.params['OrigHeight'] = height
    crack_slab.params['OrigDepth'] = depth

    crack_slab.params['YoungsModulus'] = E
    crack_slab.params['PoissonRatio_yx'] = v
    crack_slab.params['PoissonRatio_yz'] = v2

    # Open surfaces, remain periodic in z direction (normal to plane)
    # and optionally also in x direction if crack_double_ended is true
    if not params.crack_double_ended:
        crack_slab.lattice[1,1] = crack_slab.lattice[1,1] + params.crack_vacuum_size

    crack_slab.lattice[2,2] = crack_slab.lattice[2,2] + params.crack_vacuum_size
    crack_slab.set_lattice(crack_slab.lattice, False)

    # 3D crack with free surfaces at z = +/- depth/2
    if params.crack_free_surfaces:
        crack_slab.pos[3,:] -= crack_slab.pos[3,:].mean() # center on z=0
        crack_slab.lattice[3,3] = crack_slab.lattice[3,3] + params.crack_vacuum_size

    crack_slab.set_lattice(crack_slab.lattice, False)

    # Map atoms into cell AFTER changing to the new lattice
    crack_slab.map_into_cell()

    miny, maxy = crack_slab.pos[2,:].min(), crack_slab.pos[2,:].max()
    assert abs((maxy-miny) - height) < 1e-5  # be sure that remapping didn't change height of slab

    # Add various properties to crack_slab
    crack_slab.add_property('hybrid', 0)
    crack_slab.add_property('hybrid_mark', HYBRID_NO_MARK)
    crack_slab.add_property('changed_nn', 0)
    crack_slab.add_property('move_mask', 0)
    crack_slab.add_property('nn', 0)
    crack_slab.add_property('old_nn', 0)
    crack_slab.add_property('md_old_changed_nn', 0)
    crack_slab.add_property('edge_mask', 0)
    crack_slab.add_property('crack_surface', False)
    crack_slab.add_property('crack_front', False)
    if params.crack_fix_dipoles:
	crack_slab.add_property('fixdip', False)

    print_title('Fixing Atoms')

    # Fix top and bottom edges - anything within crack_edge_fix_tol of ymax or ymin is fixed

    miny, maxy = crack_slab.pos[2,:].min(), crack_slab.pos[2,:].max()

    crack_slab.move_mask[:] = 1
    crack_slab.move_mask[(abs(crack_slab.pos[2,:]-maxy) < params.crack_edge_fix_tol) |
                         (abs(crack_slab.pos[2,:]-miny) < params.crack_edge_fix_tol)] = 0

    if params.crack_fix_sides:
        maxx, minx = crack_slab.pos[1,:].min(), crack_slab.pos[1,:].max()
        crack_slab.move_mask[(abs(crack_slab.pos[1,:]-maxx) < params.crack_edge_fix_tol) |
                             (abs(crack_slab.pos[1,:]-minx) < params.crack_edge_fix_tol)] = 0


    print('%d atoms. %d fixed atoms' % (crack_slab.n, crack_slab.n - crack_slab.move_mask.sum()))

    print_title('Setting edge mask')

    crack_slab.edge_mask[:] = 0

    minx, maxx = crack_slab.pos[1,:].min(), crack_slab.pos[1,:].max()
    crack_slab.edge_mask[(abs(crack_slab.pos[1,:]-minx) < params.selection_edge_tol) |
                         (abs(crack_slab.pos[1,:]-maxx) < params.selection_edge_tol)] = 1

    miny, maxy = crack_slab.pos[2,:].min(), crack_slab.pos[2,:].max()
    crack_slab.edge_mask[(abs(crack_slab.pos[2,:]-miny) < params.selection_edge_tol) |
                         (abs(crack_slab.pos[2,:]-maxy) < params.selection_edge_tol)] = 1

    if params.crack_free_surfaces:
        # Open surfaces at +/- z
        minz, maxz = crack_slab.pos[3,:].min(), crack_slab.pos[3,:].max()
        crack_slab.edge_mask[(abs(crack_slab.pos[3,:]-minz) < params.selection_edge_tol) |
                             (abs(crack_slab.pos[3,:]-maxz) < params.selection_edge_tol)] = 1

    if params.crack_fix_dipoles:
        print_title('Fixing dipoles')
        crack_slab.fixdip[(abs(crack_slab.pos[2,:]-maxy) < params.crack_fix_dipoles_tol) |
                          (abs(crack_slab.pos[2,:]-miny) < params.crack_fix_dipoles_tol)] = 1
        if params.crack_fix_sides:
                maxx, minx = crack_slab.pos[1,:].min(), crack_slab.pos[1,:].max()
                crack_slab.fixdip[(abs(crack_slab.pos[1,:]-maxx) < params.crack_fix_dipoles_tol) |
                                  (abs(crack_slab.pos[1,:]-minx) < params.crack_fix_dipoles_tol)] = 1


    if params.crack_curved_front:
       crack_make_seed_curved_front(crack_slab, params)
    else:
       crack_make_seed(crack_slab, params)
       if params.crack_apply_initial_load:
          crack_calc_load_field(crack_slab, params, classicalpot,
                              params.crack_loading, overwrite_pos=True,
                              mpi=mpi_glob)

    crack_slab.write('dump.xyz')
    crack_update_connect(crack_slab, params)

    if not params.simulation_classical:
        if (params.selection_method.strip() == 'crack_front' or
            params.crack_tip_method.strip() == 'local_energy'):
            classicalpot.calc(crack_slab, local_energy=True)

        crack_setup_marks(crack_slab, params)
        crack_update_selection(crack_slab, params)

    if params.any_per_atom_tau():
        # Set up per_atom_tau property for ramped Langevin thermostat:
        #
        #    tau
        #    ^
        #    |\        /|                     |\        /|  max_tau
        #    | \      / |                     | \      / |
        #    |  \    /  |     constant E      |  \    /  |
        #    |   \  /   |      (tau = 0)      |   \  /   |
        #    |    \/    |                     |    \/    |
        #    +----------+---------------------+----------+---> x
        #   -w/2      -w/2+r                 w/2-r      w/2

        w_by_2   = crack_slab.OrigWidth/2.
        ramp_len = params.crack_thermostat_ramp_length
        max_tau  = params.crack_thermostat_ramp_max_tau
        print 'Adding thermostat ramp with length', ramp_len, 'max_tau', max_tau

        @np.vectorize
        def tau(x):
            if x < -w_by_2 + ramp_len/2:
                q = (x+w_by_2)/(ramp_len/2.)
                return max_tau*(1.- q)
            elif (x > -w_by_2 + ramp_len/2 and
                  x < -w_by_2 + ramp_len):
                q = (x+w_by_2-ramp_len/2.)/(ramp_len/2.)
                return max_tau*q
            elif (x > -w_by_2 + ramp_len and
                  x < w_by_2 - ramp_len):
                return 0.
            elif (x > w_by_2 - ramp_len and
                  x < w_by_2 - ramp_len/2):
                q = (x-w_by_2+ramp_len)/(ramp_len/2.)
                return max_tau*(1.- q)
            else:
                q = (x-w_by_2+ramp_len/2.)/(ramp_len/2.)
                return max_tau*q
        crack_slab.add_property('per_atom_tau', tau(crack_slab.pos[1,:]))

    return crack_slab
Beispiel #3
0
print 'Starting threaded quippy server on %s:%d with N_JOBS=%d' % (ip, port,
                                                                   N_JOBS)
server_thread.start()

t_init = time.time()

# we need an input Queue for each client: this is so that we can
# exploit wavefunction reuse by sending consecutive clusters belonging
# to the same atom to the same QM partition
input_qs = [Queue() for i in range(N_JOBS)]
output_q = Queue()
cluster_map = {}

# setup clusters to be calculated
d = diamond(5.44, 14)
at = supercell(d, 2, 2, 2)
at.rattle(0.05)
at.calc_connect()
clusters = list(
    iter_atom_centered_clusters(at, buffer_hops=4, randomise_buffer=False))

pot = Potential('IP SW', param_filename='params.xml')

for i, c in enumerate(clusters):
    client_id, nstep = i % N_JOBS, i // N_JOBS
    data = pack_atoms_to_reftraj_str(c, nstep)
    cluster_map[(client_id, nstep)] = (c, i)
    input_qs[client_id].put(data)
    pot.calc(c, args_str='energy force virial')

t_clus = time.time()
Beispiel #4
0
    configs = AtomsReader(infile,
                          start=opt.range.start,
                          stop=opt.range.stop,
                          step=opt.range.step)

    for frame, q0 in enumerate(configs):
        print 'Read %d atoms from file %s frame %d' % (q0.n, infile, frame)

        diameter = farray(0, dtype=np.int32)
        ring_sizes = range(1, opt.max_ring_size + 1)

        if opt.supercell is None:
            q = q0
        else:
            print 'Forming %d x %d x %d supercell' % tuple(opt.supercell)
            q = supercell(q0, opt.supercell[0], opt.supercell[1],
                          opt.supercell[2])
        q.map_into_cell()

        q.set_cutoff(opt.si_o_cutoff)
        q.calc_connect()

        if opt.tetra:
            print 'Converting topology from Si-O-Si to Si-Si'
            si_si, si_o, si_si_cutoff = tetrahedra_to_bonds(q)

        if opt.si_si_cutoff is None:
            opt.si_si_cutoff = si_si_cutoff

        dm = distance_map(q, q.n, q.n, diameter=diameter)
        print 'Distance map diameter %d' % diameter
        print 'Max ring size %d' % opt.max_ring_size
Beispiel #5
0
fs_lattice_parameter = 3.18
species = 74
lattice = quippy.bcc

# This is a little bit higher as python sometimes truncates 3.99
max_atoms = 512

if lattice.func_name == 'sc':
    lattice_parameter = fs_lattice_parameter*0.5*(2**0.5)
else:
    lattice_parameter = fs_lattice_parameter

# Make a cubic supercell with up to max_atoms in it
bulk = lattice(lattice_parameter, species)
n_supercell = int((float(max_atoms)/bulk.n)**(1.0/3.0))
bulk = supercell(bulk, n_supercell, n_supercell, n_supercell)

fs_potential = Potential('IP FS')
fs_potential.set_calc_args({'E_scale': 0.99519, 'r_scale': 0.99302})

bulk.set_cutoff(fs_potential.cutoff() + 2.0)
bulk.set_calculator(fs_potential)

minimiser = Minim(bulk, relax_positions=True, relax_cell=True)
minimiser.run()

TEMPERATURE = 5000
# From 10.1007/BF01184339, thermal expansion of tungsten is small, but for
# different temperatures we can expand a bit:
# 3000 K V/V0 = 1.11;
# 5000 K V/V0 = 1.29