Esempio n. 1
0
 def test_to_from_dict(self):
     op = SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12. / 13],
                  [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])
     magop = MagSymmOp.from_symmop(op, -1)
     magop2 = MagSymmOp.from_dict(magop.as_dict())
     self.assertEqual(magop2.time_reversal, -1)
     self.assertEqual(magop2.as_xyzt_string(), '3x-2y-z+1/2, -x+12/13, z+1/2, -1')
Esempio n. 2
0
 def test_to_from_dict(self):
     op = SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12. / 13],
                  [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])
     magop = MagSymmOp.from_symmop(op, -1)
     magop2 = MagSymmOp.from_dict(magop.as_dict())
     self.assertEqual(magop2.time_reversal, -1)
     self.assertEqual(magop2.as_xyzt_string(), '3x-2y-z+1/2, -x+12/13, z+1/2, -1')
Esempio n. 3
0
    def symmetry_ops(self):
        """
        Retrieve magnetic symmetry operations of the space group.
        :return: List of :class:`pymatgen.core.operations.MagSymmOp`
        """
        ops = [op_data['op'] for op_data in self._data['bns_operators']]

        # add lattice centerings
        centered_ops = []
        lattice_vectors = [l['vector'] for l in self._data['bns_lattice']]

        for vec in lattice_vectors:
            if not (np.array_equal(vec, [1, 0, 0])
                    or np.array_equal(vec, [0, 1, 0])
                    or np.array_equal(vec, [0, 0, 1])):
                for op in ops:
                    new_vec = op.translation_vector + vec
                    new_op = MagSymmOp.from_rotation_and_translation_and_time_reversal(op.rotation_matrix,
                                                                                       translation_vec=new_vec,
                                                                                       time_reversal=op.time_reversal)
                    centered_ops.append(new_op)

        ops = ops+centered_ops

        return ops
Esempio n. 4
0
        def _parse_operators(b):
            '''Parses compact binary representation into list of MagSymmOps.'''
            if len(b) == 0:  # e.g. if magtype != 4, OG setting == BNS setting, and b == [] for OG symmops
                return None
            raw_symops = [b[i:i+6] for i in range(0, len(b), 6)]

            symops = []

            for r in raw_symops:
                point_operator = _get_point_operator(r[0])
                translation_vec = [r[1]/r[4], r[2]/r[4], r[3]/r[4]]
                time_reversal = r[5]
                op = MagSymmOp.from_rotation_and_translation_and_time_reversal(rotation_matrix=point_operator['matrix'],
                                                                               translation_vec=translation_vec,
                                                                               time_reversal=time_reversal)
                # store string representation, e.g. (2x|1/2,1/2,1/2)'
                seitz = '({0}|{1},{2},{3})'.format(point_operator['symbol'],
                                                   Fraction(translation_vec[0]),
                                                   Fraction(translation_vec[1]),
                                                   Fraction(translation_vec[2]))
                if time_reversal == -1:
                    seitz += '\''
                symops.append({'op': op, 'str': seitz})

            return symops
Esempio n. 5
0
 def transform_symmop(
         self, symmop: Union[SymmOp,
                             MagSymmOp]) -> Union[SymmOp, MagSymmOp]:
     """
     Takes a symmetry operation and transforms it.
     :param symmop: SymmOp or MagSymmOp
     :return:
     """
     W = symmop.rotation_matrix
     w = symmop.translation_vector
     Q = np.linalg.inv(self.P)
     W_ = np.matmul(np.matmul(Q, W), self.P)
     I = np.identity(3)
     w_ = np.matmul(Q, (w + np.matmul(W - I, self.p)))
     w_ = np.mod(w_, 1.0)
     if isinstance(symmop, MagSymmOp):
         return MagSymmOp.from_rotation_and_translation_and_time_reversal(
             rotation_matrix=W_,
             translation_vec=w_,
             time_reversal=symmop.time_reversal,
             tol=symmop.tol,
         )
     if isinstance(symmop, SymmOp):
         return SymmOp.from_rotation_and_translation(rotation_matrix=W_,
                                                     translation_vec=w_,
                                                     tol=symmop.tol)
     raise RuntimeError
Esempio n. 6
0
    def symmetry_ops(self):
        """
        Retrieve magnetic symmetry operations of the space group.
        :return: List of :class:`pymatgen.core.operations.MagSymmOp`
        """
        ops = [op_data["op"] for op_data in self._data["bns_operators"]]

        # add lattice centerings
        centered_ops = []
        lattice_vectors = [l["vector"] for l in self._data["bns_lattice"]]

        for vec in lattice_vectors:
            if not (np.array_equal(vec, [1, 0, 0]) or np.array_equal(
                    vec, [0, 1, 0]) or np.array_equal(vec, [0, 0, 1])):
                for op in ops:
                    new_vec = op.translation_vector + vec
                    new_op = MagSymmOp.from_rotation_and_translation_and_time_reversal(
                        op.rotation_matrix,
                        translation_vec=new_vec,
                        time_reversal=op.time_reversal,
                    )
                    centered_ops.append(new_op)

        ops = ops + centered_ops

        # apply jones faithful transformation
        ops = [self.jf.transform_symmop(op) for op in ops]

        return ops
Esempio n. 7
0
        def _parse_operators(b):
            """Parses compact binary representation into list of MagSymmOps."""
            if len(
                    b
            ) == 0:  # e.g. if magtype != 4, OG setting == BNS setting, and b == [] for OG symmops
                return None
            raw_symops = [b[i:i + 6] for i in range(0, len(b), 6)]

            symops = []

            for r in raw_symops:
                point_operator = _get_point_operator(r[0])
                translation_vec = [r[1] / r[4], r[2] / r[4], r[3] / r[4]]
                time_reversal = r[5]
                op = MagSymmOp.from_rotation_and_translation_and_time_reversal(
                    rotation_matrix=point_operator["matrix"],
                    translation_vec=translation_vec,
                    time_reversal=time_reversal,
                )
                # store string representation, e.g. (2x|1/2,1/2,1/2)'
                seitz = "({0}|{1},{2},{3})".format(
                    point_operator["symbol"],
                    Fraction(translation_vec[0]),
                    Fraction(translation_vec[1]),
                    Fraction(translation_vec[2]),
                )
                if time_reversal == -1:
                    seitz += "'"
                symops.append({"op": op, "str": seitz})

            return symops
Esempio n. 8
0
    def symmetry_ops(self):
        """
        Retrieve magnetic symmetry operations of the space group.
        :return: List of :class:`pymatgen.core.operations.MagSymmOp`
        """
        ops = [op_data['op'] for op_data in self._data['bns_operators']]

        # add lattice centerings
        centered_ops = []
        lattice_vectors = [l['vector'] for l in self._data['bns_lattice']]

        for vec in lattice_vectors:
            if not (np.array_equal(vec, [1, 0, 0]) or np.array_equal(
                    vec, [0, 1, 0]) or np.array_equal(vec, [0, 0, 1])):
                for op in ops:
                    new_vec = op.translation_vector + vec
                    new_op = MagSymmOp.from_rotation_and_translation_and_time_reversal(
                        op.rotation_matrix,
                        translation_vec=new_vec,
                        time_reversal=op.time_reversal)
                    centered_ops.append(new_op)

        ops = ops + centered_ops

        return ops
Esempio n. 9
0
    def test_xyzt_string(self):

        xyzt_strings = [
            'x, y, z, +1', 'x, y, z, -1', '-y+1/2, x+1/2, x+1/2, +1'
        ]

        for xyzt_string in xyzt_strings:
            op = MagSymmOp.from_xyzt_string(xyzt_string)
            xyzt_string_out = op.as_xyzt_string()
            self.assertEqual(xyzt_string, xyzt_string_out)

        op = SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12. / 13],
                     [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])

        magop = MagSymmOp.from_symmop(op, -1)
        magop_str = magop.as_xyzt_string()
        self.assertEqual(magop.time_reversal, -1)
        self.assertEqual(magop_str, '3x-2y-z+1/2, -x+12/13, z+1/2, -1')
Esempio n. 10
0
    def test_xyzt_string(self):

        xyzt_strings = ['x, y, z, +1',
                        'x, y, z, -1',
                        '-y+1/2, x+1/2, x+1/2, +1']

        for xyzt_string in xyzt_strings:
            op = MagSymmOp.from_xyzt_string(xyzt_string)
            xyzt_string_out = op.as_xyzt_string()
            self.assertEqual(xyzt_string, xyzt_string_out)

        op = SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12. / 13],
                     [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])

        magop = MagSymmOp.from_symmop(op, -1)
        magop_str = magop.as_xyzt_string()
        self.assertEqual(magop.time_reversal, -1)
        self.assertEqual(magop_str, '3x-2y-z+1/2, -x+12/13, z+1/2, -1')
Esempio n. 11
0
    def test_operate_magmom(self):

        # all test magmoms are the same
        magmoms = [
            Magmom([1, 2, 3]),  # as Magmom
            [1, 2, 3],  # as list
            Magmom([-3, 2, 1], saxis=[1, 0, 0]),
        ]  # as Magmom with non-default saxis

        xyzt_strings = ["x, y, z, +1", "x, y, z, -1", "x, -y, z, -1", "-x, -y, z, -1"]

        transformed_magmoms = [[1, 2, 3], [-1, -2, -3], [1, -2, 3], [1, 2, -3]]

        for xyzt_string, transformed_magmom in zip(xyzt_strings, transformed_magmoms):
            for magmom in magmoms:
                op = MagSymmOp.from_xyzt_string(xyzt_string)
                self.assertTrue(np.allclose(transformed_magmom, op.operate_magmom(magmom).global_moment))
Esempio n. 12
0
 def transform_symmop(self, symmop):
     # type: (Union[SymmOp, MagSymmOp]) -> Union[SymmOp, MagSymmOp]
     """
     Takes a symmetry operation and transforms it.
     :param symmop: SymmOp or MagSymmOp
     :return: 
     """
     W = symmop.rotation_matrix
     w = symmop.translation_vector
     Q = np.linalg.inv(self.P)
     W_ = np.matmul(np.matmul(Q, W), self.P)
     I = np.identity(3)
     w_ = np.matmul(Q, (w + np.matmul(W - I, self.p)))
     if isinstance(symmop, MagSymmOp):
         return MagSymmOp.from_rotation_and_translation_and_time_reversal(rotation_matrix=W_,
                                                                          translation_vec=w_,
                                                                          time_reversal=symmop.time_reversal,
                                                                          tol=symmop.tol)
     elif isinstance(symmop, SymmOp):
         return SymmOp.from_rotation_and_translation(rotation_matrix=W_, translation_vec=w_, tol=symmop.tol)
Esempio n. 13
0
    def test_operate_magmom(self):

        # all test magmoms are the same
        magmoms = [Magmom([1, 2, 3]),  # as Magmom
                   [1, 2, 3],  # as list
                   Magmom([-3, 2, 1], saxis=[1, 0, 0])]  # as Magmom with non-default saxis

        xyzt_strings = ['x, y, z, +1',
                        'x, y, z, -1',
                        'x, -y, z, -1',
                        '-x, -y, z, -1']

        transformed_magmoms = [[1, 2, 3],
                               [-1, -2, -3],
                               [1, -2, 3],
                               [1, 2, -3]]

        for xyzt_string, transformed_magmom in zip(xyzt_strings, transformed_magmoms):
            for magmom in magmoms:
                op = MagSymmOp.from_xyzt_string(xyzt_string)
                self.assertTrue(np.allclose(transformed_magmom, op.operate_magmom(magmom).global_moment))
Esempio n. 14
0
    def get_magsymops(self, data):
        """
        Equivalent to get_symops except for magnetic symmetry groups.
        Separate function since additional operation for time reversal symmetry
        (which changes magnetic moments on sites) needs to be returned.
        """
        magsymmops = []

        # check to see if magCIF file explicitly contains magnetic symmetry operations
        if data.data.get("_space_group_symop_magn_operation.xyz"):

            xyzt = data.data.get("_space_group_symop_magn_operation.xyz")
            if isinstance(xyzt, six.string_types):
                xyzt = [xyzt]
            magsymmops = [MagSymmOp.from_xyzt_string(s) for s in xyzt]

            if data.data.get("_space_group_symop_magn_centering.xyz"):

                xyzt = data.data.get("_space_group_symop_magn_centering.xyz")
                if isinstance(xyzt, six.string_types):
                    xyzt = [xyzt]
                centering_symops = [
                    MagSymmOp.from_xyzt_string(s) for s in xyzt
                ]

                all_ops = []
                for op in magsymmops:
                    for centering_op in centering_symops:
                        new_translation = [
                            i - np.floor(i) for i in op.translation_vector +
                            centering_op.translation_vector
                        ]
                        new_time_reversal = op.time_reversal * centering_op.time_reversal
                        all_ops.append(
                            MagSymmOp.
                            from_rotation_and_translation_and_time_reversal(
                                rotation_matrix=op.rotation_matrix,
                                translation_vec=new_translation,
                                time_reversal=new_time_reversal))
                magsymmops = all_ops

        # else check to see if it specifies a magnetic space group
        elif data.data.get("_space_group_magn.name_BNS") or data.data.get(
                "_space_group_magn.number_BNS"):

            if data.data.get("_space_group_magn.name_BNS"):
                # get BNS label for MagneticSpaceGroup()
                id = data.data.get("_space_group_magn.name_BNS")
            else:
                # get BNS number for MagneticSpaceGroup()
                # by converting string to list of ints
                id = list(
                    map(int, (data.data.get(
                        "_space_group_magn.number_BNS").split("."))))

            msg = MagneticSpaceGroup(id)

            if data.data.get("_space_group_magn.transform_BNS_Pp_abc"):
                if data.data.get("_space_group_magn.transform_BNS_Pp_abc"
                                 ) != "a,b,c;0,0,0":
                    return NotImplementedError(
                        "Non-standard settings not currently supported.")
            elif data.data.get("_space_group_magn.transform_BNS_Pp"):
                return NotImplementedError(
                    "Incomplete specification to implement.")

            magsymmops = msg.symmetry_ops

        if not magsymmops:
            warnings.warn(
                "No magnetic symmetry detected, using primitive symmetry.")
            magsymmops = [MagSymmOp.from_xyzt_string("x, y, z, 1")]

        return magsymmops