Пример #1
0
class Bicrystal(OrthorhombicPbcModel):
    def __init__(self, lattice1, lattice2, dim, rot_u, rot_b, title):
        OrthorhombicPbcModel.__init__(self, lattice1, dim, title=title)
        self.mono_u = RotatedMonocrystal(lattice1, dim, rot_u)
        self.mono_b = RotatedMonocrystal(lattice2, dim, rot_b)


    def generate_atoms(self, z_margin=0.):
        #print "Bicrystal.generate_atoms"
        self.atoms = (self.mono_u.generate_atoms(upper=True, z_margin=z_margin)
                  + self.mono_b.generate_atoms(upper=False, z_margin=z_margin))
        print "Number of atoms in bicrystal: %i" % len(self.atoms)
        self.print_boundary_angle()

    def print_boundary_angle(self):
        def calc_angle(v1, v2):
            return acos( dot(v1, v2) / sqrt(inner(v1,v1) * inner(v2,v2)) )
        u0 = self.mono_u.unit_cell.get_unit_shift(0)
        b = [self.mono_b.unit_cell.get_unit_shift(i) for i in range(3)]
        b += [-i for i in b]
        angles = [degrees(calc_angle(u0, i)) for i in b]
        print "angles between upper and bottom:", \
                ", ".join("%.1f" % i for i in angles)
Пример #2
0
class Bicrystal(OrthorhombicPbcModel):
    def __init__(self, lattice1, lattice2, dim, rot_u, rot_b, title):
        OrthorhombicPbcModel.__init__(self, lattice1, dim, title=title)
        self.mono_u = RotatedMonocrystal(lattice1, dim, rot_u)
        self.mono_b = RotatedMonocrystal(lattice2, dim, rot_b)


    def generate_atoms(self, z_margin=0.):
        #print "Bicrystal.generate_atoms"
        self.atoms = (self.mono_u.generate_atoms(upper=True, z_margin=z_margin)
                  + self.mono_b.generate_atoms(upper=False, z_margin=z_margin))
        print "Number of atoms in bicrystal: %i" % len(self.atoms)
        self.print_boundary_angle()

    def print_boundary_angle(self):
        def calc_angle(v1, v2):
            return acos( dot(v1, v2) / sqrt(inner(v1,v1) * inner(v2,v2)) )
        u0 = self.mono_u.unit_cell.get_unit_shift(0)
        b = [self.mono_b.unit_cell.get_unit_shift(i) for i in range(3)]
        b += [-i for i in b]
        angles = [degrees(calc_angle(u0, i)) for i in b]
        print "angles between upper and bottom:", \
                ", ".join("%.1f" % i for i in angles)
Пример #3
0
 def __init__(self, lattice1, lattice2, dim, rot_u, rot_b, title):
     OrthorhombicPbcModel.__init__(self, lattice1, dim, title=title)
     self.mono_u = RotatedMonocrystal(lattice1, dim, rot_u)
     self.mono_b = RotatedMonocrystal(lattice2, dim, rot_b)
Пример #4
0
def main():
    opts = parse_args()

    # R is a matrix that transforms lattice in the bottom monocrystal
    # to lattice in the upper monocrystal
    R = rodrigues(opts.axis, opts.theta)

    if opts.sigma:
        # C is CSL primitive cell
        C = csl.find_csl_matrix(opts.sigma, R)
        print_matrix("CSL primitive cell", C)

        ## and now we determine CSL for fcc lattice
        #C = csl.pc2fcc(C)
        #C = csl.beautify_matrix(C)
        #print_matrix("CSL cell for fcc:", C)
    else:
        C = identity(3)

    # CSL-lattice must be periodic is our system.
    # * PBC box must be orthonormal
    # * boundaries must be perpendicular to z axis of PBC box

    print "CSL cell with z || [%s %s %s]" % tuple(opts.plane),
    Cp = csl.make_parallel_to_axis(C, col=2, axis=opts.plane)
    print_matrix("", Cp)

    min_pbc = csl.find_orthorhombic_pbc(Cp)
    print_matrix("Minimal(?) orthorhombic PBC", min_pbc)

    min_dim = []
    pbct = min_pbc.transpose().astype(float)
    rot = zeros((3, 3))
    for i in range(3):
        length = sqrt(inner(pbct[i], pbct[i]))
        rot[i] = pbct[i] / length
        min_dim.append(length)
    invrot = rot.transpose()
    assert (numpy.abs(invrot - linalg.inv(rot)) < 1e-9).all(), "%s != %s" % (
                                                     invrot, linalg.inv(rot))
    #print "hack warning: min_dim[1] /= 2."
    #min_dim[1] /= 2.

    if "," in opts.lattice_name:
        name1, name2 = opts.lattice_name.split(",")
        lattice1 = get_named_lattice(name1)
        lattice2 = get_named_lattice(name2)
    else:
        lattice1 = get_named_lattice(opts.lattice_name)
        lattice2 = deepcopy(lattice1)

    if opts.lattice_shift:
        lattice1.shift_nodes(opts.lattice_shift)
        lattice2.shift_nodes(opts.lattice_shift)

    # the anti-phase GB can be made by swapping two species in one grain
    if opts.antiphase:
        assert lattice2.count_species() == 2
        lattice2.swap_node_atoms_names()

    a = lattice1.unit_cell.a
    opts.find_dim([i * a for i in min_dim])

    #rot_mat1 = rodrigues(opts.axis, rot1)
    #rot_mat2 = rodrigues(opts.axis, rot2)
    rot_mat1 = dot(linalg.inv(R), invrot)
    rot_mat2 = invrot
    #print "rot1", "det=%g" % linalg.det(rot_mat1), rot_mat1
    #print "rot2", "det=%g" % linalg.det(rot_mat2), rot_mat2

    title = get_command_line()
    if opts.mono1:
        config = RotatedMonocrystal(lattice1, opts.dim, rot_mat1,
                                    title=title)
    elif opts.mono2:
        config = RotatedMonocrystal(lattice2, opts.dim, rot_mat2,
                                    title=title)
    else:
        config = Bicrystal(lattice1, lattice2, opts.dim, rot_mat1, rot_mat2,
                           title=title)
    config.generate_atoms(z_margin=opts.vacuum)

    if not opts.mono1 and not opts.mono2 and opts.remove_dist > 0:
        print "Removing atoms in distance < %s ..." % opts.remove_dist
        config.remove_close_neighbours(opts.remove_dist)

    if opts.remove_dist2:
        a_atoms = []
        b_atoms = []
        a_name = config.atoms[0].name
        for i in config.atoms:
            if i.name == a_name:
                a_atoms.append(i)
            else:
                b_atoms.append(i)
        config.atoms = []
        for aa in a_atoms, b_atoms:
            print "Removing atoms where %s-%s distance is < %s ..." % (
                                     aa[0].name, aa[0].name, opts.remove_dist2)
            config.remove_close_neighbours(distance=opts.remove_dist2, atoms=aa)
            config.atoms += aa

    if opts.edge:
        z1, z2 = opts.edge
        sel = [n for n, a in enumerate(config.atoms)
               if 0 < a.pos[1] <= config.pbc[1][1] / 2. and z1 < a.pos[2] < z2]
        print "edge: %d atoms is removed" % len(sel)
        for i in reversed(sel):
            del config.atoms[i]

    if opts.all:
        #config.output_all_removal_possibilities(opts.output_filename)
        config.apply_all_possible_cutoffs_to_stgb(opts.output_filename,
                                                  single_cutoff=True)
        return

    if opts.allall:
        config.apply_all_possible_cutoffs_to_stgb(opts.output_filename,
                                                  single_cutoff=False)
        return

    config.export_atoms(opts.output_filename)
Пример #5
0
 def __init__(self, lattice1, lattice2, dim, rot_u, rot_b, title):
     OrthorhombicPbcModel.__init__(self, lattice1, dim, title=title)
     self.mono_u = RotatedMonocrystal(lattice1, dim, rot_u)
     self.mono_b = RotatedMonocrystal(lattice2, dim, rot_b)
Пример #6
0
def main():
    opts = parse_args()

    # R is a matrix that transforms lattice in the bottom monocrystal
    # to lattice in the upper monocrystal
    R = rodrigues(opts.axis, opts.theta)

    if opts.sigma:
        # C is CSL primitive cell
        C = csl.find_csl_matrix(opts.sigma, R)
        print_matrix("CSL primitive cell", C)

        ## and now we determine CSL for fcc lattice
        #C = csl.pc2fcc(C)
        #C = csl.beautify_matrix(C)
        #print_matrix("CSL cell for fcc:", C)
    else:
        C = identity(3)

    # CSL-lattice must be periodic is our system.
    # * PBC box must be orthonormal
    # * boundaries must be perpendicular to z axis of PBC box

    print "CSL cell with z || [%s %s %s]" % tuple(opts.plane),
    Cp = csl.make_parallel_to_axis(C, col=2, axis=opts.plane)
    print_matrix("", Cp)

    min_pbc = csl.find_orthorhombic_pbc(Cp)
    print_matrix("Minimal(?) orthorhombic PBC", min_pbc)

    min_dim = []
    pbct = min_pbc.transpose().astype(float)
    rot = zeros((3, 3))
    for i in range(3):
        length = sqrt(inner(pbct[i], pbct[i]))
        rot[i] = pbct[i] / length
        min_dim.append(length)
    invrot = rot.transpose()
    assert (numpy.abs(invrot - linalg.inv(rot)) <
            1e-9).all(), "%s != %s" % (invrot, linalg.inv(rot))
    #print "hack warning: min_dim[1] /= 2."
    #min_dim[1] /= 2.

    if "," in opts.lattice_name:
        name1, name2 = opts.lattice_name.split(",")
        lattice1 = get_named_lattice(name1)
        lattice2 = get_named_lattice(name2)
    else:
        lattice1 = get_named_lattice(opts.lattice_name)
        lattice2 = deepcopy(lattice1)

    if opts.lattice_shift:
        lattice1.shift_nodes(opts.lattice_shift)
        lattice2.shift_nodes(opts.lattice_shift)

    # the anti-phase GB can be made by swapping two species in one grain
    if opts.antiphase:
        assert lattice2.count_species() == 2
        lattice2.swap_node_atoms_names()

    a = lattice1.unit_cell.a
    opts.find_dim([i * a for i in min_dim])

    #rot_mat1 = rodrigues(opts.axis, rot1)
    #rot_mat2 = rodrigues(opts.axis, rot2)
    rot_mat1 = dot(linalg.inv(R), invrot)
    rot_mat2 = invrot
    #print "rot1", "det=%g" % linalg.det(rot_mat1), rot_mat1
    #print "rot2", "det=%g" % linalg.det(rot_mat2), rot_mat2

    title = get_command_line()
    if opts.mono1:
        config = RotatedMonocrystal(lattice1, opts.dim, rot_mat1, title=title)
    elif opts.mono2:
        config = RotatedMonocrystal(lattice2, opts.dim, rot_mat2, title=title)
    else:
        config = Bicrystal(lattice1,
                           lattice2,
                           opts.dim,
                           rot_mat1,
                           rot_mat2,
                           title=title)
    config.generate_atoms(z_margin=opts.vacuum)

    if not opts.mono1 and not opts.mono2 and opts.remove_dist > 0:
        print "Removing atoms in distance < %s ..." % opts.remove_dist
        config.remove_close_neighbours(opts.remove_dist)

    if opts.remove_dist2:
        a_atoms = []
        b_atoms = []
        a_name = config.atoms[0].name
        for i in config.atoms:
            if i.name == a_name:
                a_atoms.append(i)
            else:
                b_atoms.append(i)
        config.atoms = []
        for aa in a_atoms, b_atoms:
            print "Removing atoms where %s-%s distance is < %s ..." % (
                aa[0].name, aa[0].name, opts.remove_dist2)
            config.remove_close_neighbours(distance=opts.remove_dist2,
                                           atoms=aa)
            config.atoms += aa

    if opts.edge:
        z1, z2 = opts.edge
        sel = [
            n for n, a in enumerate(config.atoms)
            if 0 < a.pos[1] <= config.pbc[1][1] / 2. and z1 < a.pos[2] < z2
        ]
        print "edge: %d atoms is removed" % len(sel)
        for i in reversed(sel):
            del config.atoms[i]

    if opts.all:
        #config.output_all_removal_possibilities(opts.output_filename)
        config.apply_all_possible_cutoffs_to_stgb(opts.output_filename,
                                                  single_cutoff=True)
        return

    if opts.allall:
        config.apply_all_possible_cutoffs_to_stgb(opts.output_filename,
                                                  single_cutoff=False)
        return

    config.export_atoms(opts.output_filename)