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')
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
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
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
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
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
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
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')
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')
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))
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)
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))
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