def get_aligned_lattices(slab_sub, slab_2d, max_area=200,
                         max_mismatch=0.05,
                         max_angle_diff=1, r1r2_tol=0.2):
    """
    given the 2 slab structures and the alignment paramters, return
    slab structures with lattices that are aligned with respect to each
    other
    """
    # get the matching substrate and 2D material lattices
    uv_substrate, uv_mat2d = get_matching_lattices(slab_sub, slab_2d,
                                                   max_area=max_area,
                                                   max_mismatch=max_mismatch,
                                                   max_angle_diff=max_angle_diff,
                                                   r1r2_tol=r1r2_tol)
    if not uv_substrate and not uv_mat2d:
        print("no matching u and v, trying adjusting the parameters")
        sys.exit()
    substrate = Structure.from_sites(slab_sub)
    mat2d = Structure.from_sites(slab_2d)
    # map the intial slabs to the newly found matching lattices
    substrate_latt = Lattice(np.array(
            [
                uv_substrate[0][:],
                uv_substrate[1][:],
                substrate.lattice.matrix[2, :]
            ]))
    # to avoid numerical issues with find_mapping
    mat2d_fake_c = mat2d.lattice.matrix[2, :] / np.linalg.norm(mat2d.lattice.matrix[2, :]) * 5.0
    mat2d_latt = Lattice(np.array(
            [
                uv_mat2d[0][:],
                uv_mat2d[1][:],
                mat2d_fake_c
            ]))
    mat2d_latt_fake = Lattice(np.array(
            [
                mat2d.lattice.matrix[0, :],
                mat2d.lattice.matrix[1, :],
                mat2d_fake_c
            ]))
    _, __, scell = substrate.lattice.find_mapping(substrate_latt,
                                                  ltol=0.05,
                                                  atol=1)
    scell[2] = np.array([0, 0, 1])
    substrate.make_supercell(scell)
    _, __, scell = mat2d_latt_fake.find_mapping(mat2d_latt,
                                                ltol=0.05,
                                                atol=1)
    scell[2] = np.array([0, 0, 1])
    mat2d.make_supercell(scell)
    # modify the substrate lattice so that the 2d material can be
    # grafted on top of it
    lmap = Lattice(np.array(
            [
                substrate.lattice.matrix[0, :],
                substrate.lattice.matrix[1, :],
                mat2d.lattice.matrix[2, :]
            ]))
    mat2d.modify_lattice(lmap)
    return substrate, mat2d
def get_aligned_lattices(slab_sub,
                         slab_2d,
                         max_area=200,
                         max_mismatch=0.05,
                         max_angle_diff=1,
                         r1r2_tol=0.2):
    """
    given the 2 slab structures and the alignment paramters, return
    slab structures with lattices that are aligned with respect to each
    other
    """
    # get the matching substrate and 2D material lattices
    uv_substrate, uv_mat2d = get_matching_lattices(
        slab_sub,
        slab_2d,
        max_area=max_area,
        max_mismatch=max_mismatch,
        max_angle_diff=max_angle_diff,
        r1r2_tol=r1r2_tol)
    if not uv_substrate and not uv_mat2d:
        print("no matching u and v, trying adjusting the parameters")
        sys.exit()
    substrate = Structure.from_sites(slab_sub)
    mat2d = Structure.from_sites(slab_2d)
    # map the intial slabs to the newly found matching lattices
    substrate_latt = Lattice(
        np.array([
            uv_substrate[0][:], uv_substrate[1][:],
            substrate.lattice.matrix[2, :]
        ]))
    # to avoid numerical issues with find_mapping
    mat2d_fake_c = mat2d.lattice.matrix[2, :] / np.linalg.norm(
        mat2d.lattice.matrix[2, :]) * 5.0
    mat2d_latt = Lattice(
        np.array([uv_mat2d[0][:], uv_mat2d[1][:], mat2d_fake_c]))
    mat2d_latt_fake = Lattice(
        np.array([
            mat2d.lattice.matrix[0, :], mat2d.lattice.matrix[1, :],
            mat2d_fake_c
        ]))
    _, __, scell = substrate.lattice.find_mapping(substrate_latt,
                                                  ltol=0.05,
                                                  atol=1)
    scell[2] = np.array([0, 0, 1])
    substrate.make_supercell(scell)
    _, __, scell = mat2d_latt_fake.find_mapping(mat2d_latt, ltol=0.05, atol=1)
    scell[2] = np.array([0, 0, 1])
    mat2d.make_supercell(scell)
    # modify the substrate lattice so that the 2d material can be
    # grafted on top of it
    lmap = Lattice(
        np.array([
            substrate.lattice.matrix[0, :], substrate.lattice.matrix[1, :],
            mat2d.lattice.matrix[2, :]
        ]))
    mat2d.modify_lattice(lmap)
    return substrate, mat2d
示例#3
0
    def test_find_mapping(self):
        m = np.array([[0.1, 0.2, 0.3], [-0.1, 0.2, 0.7], [0.6, 0.9, 0.2]])
        latt = Lattice(m)

        op = SymmOp.from_origin_axis_angle([0, 0, 0], [2, 3, 3], 35)
        rot = op.rotation_matrix
        scale = np.array([[1, 1, 0], [0, 1, 0], [0, 0, 1]])

        latt2 = Lattice(np.dot(rot, np.dot(scale, m).T).T)
        (latt, rot, scale2) = latt2.find_mapping(latt)
        self.assertAlmostEqual(abs(np.linalg.det(rot)), 1)
        self.assertTrue(np.allclose(scale2, scale) or
                        np.allclose(scale2, -scale))
示例#4
0
    def test_find_mapping(self):
        m = np.array([[0.1, 0.2, 0.3], [-0.1, 0.2, 0.7], [0.6, 0.9, 0.2]])
        latt = Lattice(m)

        op = SymmOp.from_origin_axis_angle([0, 0, 0], [2, 3, 3], 35)
        rot = op.rotation_matrix
        scale = np.array([[1, 1, 0], [0, 1, 0], [0, 0, 1]])

        latt2 = Lattice(np.dot(rot, np.dot(scale, m).T).T)
        (latt, rot, scale2) = latt2.find_mapping(latt)
        self.assertAlmostEqual(abs(np.linalg.det(rot)), 1)
        self.assertTrue(
            np.allclose(scale2, scale) or np.allclose(scale2, -scale))
示例#5
0
    def test_find_mapping(self):
        m = np.array([[0.1, 0.2, 0.3], [-0.1, 0.2, 0.7], [0.6, 0.9, 0.2]])
        latt = Lattice(m)

        op = SymmOp.from_origin_axis_angle([0, 0, 0], [2, 3, 3], 35)
        rot = op.rotation_matrix
        scale = np.array([[1, 1, 0], [0, 1, 0], [0, 0, 1]])

        latt2 = Lattice(np.dot(rot, np.dot(scale, m).T).T)
        (aligned_out, rot_out, scale_out) = latt2.find_mapping(latt)
        self.assertAlmostEqual(abs(np.linalg.det(rot)), 1)

        rotated = SymmOp.from_rotation_and_translation(rot_out).operate_multi(latt.matrix)

        self.assertArrayAlmostEqual(rotated, aligned_out.matrix)
        self.assertArrayAlmostEqual(np.dot(scale_out, latt2.matrix), aligned_out.matrix)
        self.assertArrayAlmostEqual(aligned_out.parameters, latt.parameters)
        self.assertFalse(np.allclose(aligned_out.parameters, latt2.parameters))
示例#6
0
    def test_find_mapping(self):
        m = np.array([[0.1, 0.2, 0.3], [-0.1, 0.2, 0.7], [0.6, 0.9, 0.2]])
        latt = Lattice(m)

        op = SymmOp.from_origin_axis_angle([0, 0, 0], [2, 3, 3], 35)
        rot = op.rotation_matrix
        scale = np.array([[1, 1, 0], [0, 1, 0], [0, 0, 1]])

        latt2 = Lattice(np.dot(rot, np.dot(scale, m).T).T)
        (aligned_out, rot_out, scale_out) = latt2.find_mapping(latt)
        self.assertAlmostEqual(abs(np.linalg.det(rot)), 1)

        rotated = SymmOp.from_rotation_and_translation(rot_out).operate_multi(latt.matrix)

        self.assertArrayAlmostEqual(rotated, aligned_out.matrix)
        self.assertArrayAlmostEqual(np.dot(scale_out, latt2.matrix), aligned_out.matrix)
        self.assertArrayAlmostEqual(aligned_out.lengths_and_angles, latt.lengths_and_angles)
        self.assertFalse(np.allclose(aligned_out.lengths_and_angles,
                                     latt2.lengths_and_angles))
示例#7
0
    def process_sys(
        slab_sub,
        slab_2d,
        uv_substrate,
        uv_mat2d,
        ):
        """
        """
        #| - process_sys
        substrate = Structure.from_sites(slab_sub)
        mat2d = Structure.from_sites(slab_2d)
        # map the intial slabs to the newly found matching lattices
        substrate_latt = Lattice(
            np.array(
                [
                    uv_substrate[0][:],
                    uv_substrate[1][:],
                    substrate.lattice.matrix[2, :]
                    ]
                )
            )

        # to avoid numerical issues with find_mapping
        mat2d_fake_c = mat2d.lattice.matrix[2, :] / np.linalg.norm(
            mat2d.lattice.matrix[2, :]) * 5.0
        mat2d_latt = Lattice(
            np.array(
                [
                    uv_mat2d[0][:],
                    uv_mat2d[1][:],
                    mat2d_fake_c
                    ]
                )
            )

        mat2d_latt_fake = Lattice(
            np.array(
                [
                    mat2d.lattice.matrix[0, :],
                    mat2d.lattice.matrix[1, :],
                    mat2d_fake_c
                    ]
                )
            )

        _, __, scell = substrate.lattice.find_mapping(substrate_latt,
                                                      ltol=0.05,
                                                      atol=1)
        scell[2] = np.array([0, 0, 1])
        substrate.make_supercell(scell)
        _, __, scell = mat2d_latt_fake.find_mapping(mat2d_latt,
                                                    ltol=0.05,
                                                    atol=1)
        scell[2] = np.array([0, 0, 1])
        mat2d.make_supercell(scell)
        # modify the substrate lattice so that the 2d material can be
        # grafted on top of it
        lmap = Lattice(
            np.array(
                [
                    substrate.lattice.matrix[0, :],
                    substrate.lattice.matrix[1, :],
                    mat2d.lattice.matrix[2, :]
                    ]
                )
            )

        mat2d.modify_lattice(lmap)

        return(substrate, mat2d)
示例#8
0
def mismatch_strts(film=[], subs=[]):

    z = ZSLGenerator()
    matches = list(
        z(film.lattice.matrix[:2], subs.lattice.matrix[:2], lowest=True))
    info = {}
    info["mismatch_u"] = "na"
    info["mismatch_v"] = "na"
    info["mismatch_angle"] = "na"
    info["area1"] = "na"
    info["area2"] = "na"
    info["film_sl"] = film
    info["subs_sl"] = subs

    try:
        uv1 = matches[0]["sub_sl_vecs"]
        uv2 = matches[0]["film_sl_vecs"]
        # uv1=[[-8.52917200e+00,  9.12745800e+00,  3.66344517e-17],[1.27937580e+01, 9.12745800e+00, 1.34228735e-15]]
        # uv2=[[7.02403800e+00, 1.05360570e+01, 1.07524571e-15],[-1.40480760e+01,  7.02403800e+00, -4.30098283e-16]]
        u = np.array(uv1)
        v = np.array(uv2)
        a1 = u[0]
        a2 = u[1]
        b1 = v[0]
        b2 = v[1]
        mismatch_u = np.linalg.norm(b1) / np.linalg.norm(a1) - 1
        mismatch_v = np.linalg.norm(b2) / np.linalg.norm(a2) - 1
        angle1 = (np.arccos(
            np.dot(a1, a2) / np.linalg.norm(a1) / np.linalg.norm(a2)) * 180 /
                  np.pi)
        angle2 = (np.arccos(
            np.dot(b1, b2) / np.linalg.norm(b1) / np.linalg.norm(b2)) * 180 /
                  np.pi)
        mismatch_angle = abs(angle1 - angle2)
        area1 = np.linalg.norm(np.cross(a1, a2))
        area2 = np.linalg.norm(np.cross(b1, b2))
        uv_substrate = uv1
        uv_mat2d = uv2
        substrate_latt = Lattice(
            np.array([
                uv_substrate[0][:], uv_substrate[1][:],
                subs.lattice.matrix[2, :]
            ]))
        # to avoid numerical issues with find_mapping
        mat2d_fake_c = (film.lattice.matrix[2, :] /
                        np.linalg.norm(film.lattice.matrix[2, :]) * 5.0)
        mat2d_latt = Lattice(
            np.array([uv_mat2d[0][:], uv_mat2d[1][:], mat2d_fake_c]))
        mat2d_latt_fake = Lattice(
            np.array([
                film.lattice.matrix[0, :], film.lattice.matrix[1, :],
                mat2d_fake_c
            ]))
        _, __, scell = subs.lattice.find_mapping(substrate_latt,
                                                 ltol=0.05,
                                                 atol=1)
        scell[2] = np.array([0, 0, 1])
        subs.make_supercell(scell)
        _, __, scell = mat2d_latt_fake.find_mapping(mat2d_latt,
                                                    ltol=0.05,
                                                    atol=1)
        scell[2] = np.array([0, 0, 1])
        film.make_supercell(scell)
        # modify the substrate lattice so that the 2d material can be
        # grafted on top of it
        lmap = Lattice(
            np.array([
                subs.lattice.matrix[0, :],
                subs.lattice.matrix[1, :],
                film.lattice.matrix[2, :],
            ]))
        film.modify_lattice(lmap)
        # print ("film",film)
        # print ("subs",subs)

        info["mismatch_u"] = mismatch_u
        info["mismatch_v"] = mismatch_v
        info["mismatch_angle"] = mismatch_angle
        info["area1"] = area1
        info["area2"] = area2
        info["film_sl"] = film
        info["subs_sl"] = subs
    except:
        pass
    return info