Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
3rd index: a site symmetry SymmOp of the point
Args:
num: the Rod group number
molecular: whether or not to return the Euclidean point symmetry
operations. If True, cuts off translational part of operation, and
converts non-orthogonal operations (3-fold and 6-fold rotations)
to (orthogonal) pure rotations. Should be used when dealing with
molecular crystals
Returns:
a 3d list of SymmOp objects representing the site symmetry of each
point in each Wyckoff position
"""
P = SymmOp.from_rotation_and_translation(
[[1, -0.5, 0], [0, np.sqrt(3) / 2, 0], [0, 0, 1]], [0, 0, 0]
)
symmetry_strings = eval(rod_symmetry_df["0"][num])
symmetry = []
convert = False
if molecular is True:
if num >= 42:
convert = True
# Loop over Wyckoff positions
for x in symmetry_strings:
symmetry.append([])
# Loop over points in WP
for y in x:
symmetry[-1].append([])
# Loop over ops
for z in y:
if molecular is True:
if num >= 65:
convert = True
# Loop over Wyckoff positions
for x in generator_strings:
generators.append([])
# Loop over ops
for y in x:
op = SymmOp.from_xyz_string(y)
if convert is True:
# Convert non-orthogonal trigonal/hexagonal operations
op = P * op * P.inverse
if molecular is False:
generators[-1].append(op)
elif molecular is True:
op = SymmOp.from_rotation_and_translation(op.rotation_matrix, [0, 0, 0])
generators[-1].append(op)
return generators
if molecular is True:
if num >= 42:
convert = True
# Loop over Wyckoff positions
for x in generator_strings:
generators.append([])
# Loop over ops
for y in x:
op = SymmOp.from_xyz_string(y)
if convert is True:
# Convert non-orthogonal trigonal/hexagonal operations
op = P * op * P.inverse
if molecular is False:
generators[-1].append(op)
elif molecular is True:
op = SymmOp.from_rotation_and_translation(op.rotation_matrix, [0, 0, 0])
generators[-1].append(op)
return generators
a 3x3 matrix representing the lattice vectors of the unit cell
PBC: A periodic boundary condition list, where 1 means periodic, 0 means not periodic.
Ex: [1,1,1] -> full 3d periodicity, [0,0,1] -> periodicity along the z axis.
Need not be defined here if gen_pos is a Wyckoff_position object.
Returns:
a list of SymmOp objects which leave the given point invariant
"""
if PBC == None:
if type(gen_pos) == Wyckoff_position:
PBC = gen_pos.PBC
else:
PBC = [1, 1, 1]
# Convert point into a SymmOp
if type(point) != SymmOp:
point = SymmOp.from_rotation_and_translation(
[[0, 0, 0], [0, 0, 0], [0, 0, 0]], np.array(point)
)
symmetry = []
for op in gen_pos:
is_symmetry = True
# Calculate the effect of applying op to point
difference = SymmOp((op * point).affine_matrix - point.affine_matrix)
# Check that the rotation matrix is unaltered by op
if not np.allclose(
difference.rotation_matrix, np.zeros((3, 3)), rtol=1e-3, atol=1e-3
):
is_symmetry = False
# Check that the displacement is less than tol
displacement = difference.translation_vector
if distance(displacement, lattice, PBC=PBC) > tol:
is_symmetry = False
def reorient(mol):
new_mol = mol.get_centered_molecule()
A = get_inertia_tensor(new_mol)
# Store the eigenvectors of the inertia tensor
P = np.transpose(np.linalg.eigh(A)[1])
if np.linalg.det(P) < 0:
P[0] *= -1
# reorient the molecule
P = SymmOp.from_rotation_and_translation(P, [0, 0, 0])
new_mol.apply_operation(P)
# Our molecule should never be inverted during reorientation.
if np.linalg.det(P.rotation_matrix) < 0:
printx(
"Error: inverted reorientation applied.\n"
+ "(Within reoriented_molecule)",
priority=0,
)
return new_mol, P
symmetry[-1][-1].append(op)
else:
symmetry.append([])
# Loop over points in WP
for y in x:
symmetry[-1].append([])
# Loop over ops
for z in y:
op = SymmOp.from_xyz_string(z)
if convert is True:
# Convert non-orthogonal trigonal/hexagonal operations
op = P * op * P.inverse
if molecular is False:
symmetry[-1][-1].append(op)
elif molecular is True:
op = SymmOp.from_rotation_and_translation(
op.rotation_matrix, [0, 0, 0]
)
symmetry[-1][-1].append(op)
return symmetry
pga = PointGroupAnalyzer(mol)
# Handle linear molecules
if "*" in pga.sch_symbol:
if already_oriented == False:
# Reorient the molecule
oriented_mol, P = reoriented_molecule(mol)
pga = PointGroupAnalyzer(oriented_mol)
pg = pga.get_pointgroup()
symm_m = []
for op in pg:
symm_m.append(op)
# Add 12-fold and reflections in place of ininitesimal rotation
for axis in [[1, 0, 0], [0, 1, 0], [0, 0, 1]]:
# op = SymmOp.from_rotation_and_translation(aa2matrix(axis, np.pi/6), [0,0,0])
m1 = Rotation.from_rotvec(np.pi / 6 * axis).as_matrix()
op = SymmOp.from_rotation_and_translation(m1, [0, 0, 0])
if pga.is_valid_op(op):
symm_m.append(op)
# Any molecule with infinitesimal symmetry is linear;
# Thus, it possess mirror symmetry for any axis perpendicular
# To the rotational axis. pymatgen does not add this symmetry
# for all linear molecules - for example, hydrogen
if axis == [1, 0, 0]:
symm_m.append(SymmOp.from_xyz_string("x,-y,z"))
symm_m.append(SymmOp.from_xyz_string("x,y,-z"))
r = SymmOp.from_xyz_string("-x,y,-z")
elif axis == [0, 1, 0]:
symm_m.append(SymmOp.from_xyz_string("-x,y,z"))
symm_m.append(SymmOp.from_xyz_string("x,y,-z"))
r = SymmOp.from_xyz_string("-x,-y,z")
elif axis == [0, 0, 1]:
symm_m.append(SymmOp.from_xyz_string("-x,y,z"))
to (orthogonal) pure rotations. Should be used when dealing with
molecular crystals
Returns:
a 2d list of SymmOp objects which can be used to generate a Wyckoff position given a
single fractional (x,y,z) coordinate
"""
if PBC != [1, 1, 1]:
coor = [0, 0, 0]
for i, a in enumerate(PBC):
if not a:
coor[i] = 0.5
coor = np.array(coor)
wyckoffs = get_wyckoffs(sg, PBC=PBC)
P = SymmOp.from_rotation_and_translation(
[[1, -0.5, 0], [0, np.sqrt(3) / 2, 0], [0, 0, 1]], [0, 0, 0]
)
generator_strings = eval(wyckoff_generators_df["0"][sg])
generators = []
convert = False
if molecular is True:
if sg >= 143 and sg <= 194:
convert = True
# Loop over Wyckoff positions
for x, w in zip(generator_strings, wyckoffs):
if PBC != [1, 1, 1]:
op = w[0]
coor1 = op.operate(coor)
invalid = False
for i, a in enumerate(PBC):
if not a:
printx("Error: Invalid point group symbol.", priority=1)
return
if num == 0:
# infinite-order rotation
gens.append(SymmOp.from_xyz_string("-x,-y,-z"))
gens.append(SymmOp.from_xyz_string("x,y,-z"))
self.symbol = "C*i"
generate = False
else:
# Add rotoinversion
m = np.dot(
aa2matrix([0.0, 0.0, 1.0], 2 * np.pi / num),
[[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]],
)
gens.append(
SymmOp.from_rotation_and_translation(m, [0.0, 0.0, 0.0])
)
if num == 1:
self.symbol = "Ci"
else:
self.symbol = "C" + str(num) + "i"
if num != 1:
gen_ops = [Identity, op_z, op_o]
elif num == 1:
gen_ops = [Identity, op_o]
elif (symbol[0] == "D") and ("v" not in symbol) and ("i" not in symbol):
# n-fold rotation and n 2-fold perpendicular rotations
if num == 2 and symbol[-1] == "h":
self.lattice_type = "spherical"
else:
self.lattice_type = "ellipsoidal"