Skip to content

Commit

Permalink
finalize spg_symmetry_table and prep for v0.6.6
Browse files Browse the repository at this point in the history
  • Loading branch information
qzhu2017 committed May 6, 2024
1 parent 0569db4 commit 5de65f5
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 33 deletions.
51 changes: 48 additions & 3 deletions doc/Usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -864,8 +864,8 @@ To access the pyxtal structure
H3C4O4 @ [ 0.5328 0.0993 0.0601] WP [4a] Site [1] Euler [ 0.0 0.0 0.0]
Site Symmetry
--------------------------------
Space Group and Site Symmetry table
-----------------------------------
PyXtal provides a
`site_symmetry <pyxtal.symmetry.html#pyxtal.symmetry.site_symmetry>`_ class to handle the conversion of site symmetry symbols and operations.
Expand Down Expand Up @@ -972,7 +972,7 @@ Possible combinations include
['1', '-1', '2', 'm', '3', '-3', '6', '-6', '6/m']
Finally, a one-hot matrix representation `(15, 13)` can also be obtained via
The one-hot matrix representation `(15, 13)` can also be obtained via
.. code-block:: Python
Expand All @@ -997,3 +997,48 @@ Finally, a one-hot matrix representation `(15, 13)` can also be obtained via
[1 0 0 0 0 0 0 0 0 0 0 0 0] # 1
[1 0 0 0 0 0 0 0 0 0 0 0 0] # 1
]
Finally, the both Group and Wyckoff_position classes support the access of the symmetry element analysis via
.. code-block:: Python
from pyxtal.symmetry import Group
g = Group(14)
ss_spg = g.get_spg_symmetry_object()
print('Space group symmetry table', g.number, g.symbol)
ss_spg.to_beautiful_matrix_representation()
for wp in g:
print('\nWp symmetry table', wp.get_label())
ss_wp = wp.get_site_symmetry_object()
ss_wp.to_beautiful_matrix_representation()
::
Space group symmetry table 14 P21/c
Order Axis 1 -1 2 2_1 m a b c n d 3 3_1 3_2 4 -4 4_1 4_2 4_3 -3 6 6_1 6_2 6_3 6_4 6_5 -6
0 ( 0 1 0): 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Wp symmetry table 4e
Order Axis 1 -1 2 m 3 4 -4 -3 6 -6
0 ( 0 1 0): 1 0 0 0 0 0 0 0 0 0 1
Wp symmetry table 2d
Order Axis 1 -1 2 m 3 4 -4 -3 6 -6
0 ( 0 1 0): 1 1 0 0 0 0 0 0 0 0 -1
Wp symmetry table 2c
Order Axis 1 -1 2 m 3 4 -4 -3 6 -6
0 ( 0 1 0): 1 1 0 0 0 0 0 0 0 0 -1
Wp symmetry table 2b
Order Axis 1 -1 2 m 3 4 -4 -3 6 -6
0 ( 0 1 0): 1 1 0 0 0 0 0 0 0 0 -1
Wp symmetry table 2a
Order Axis 1 -1 2 m 3 4 -4 -3 6 -6
0 ( 0 1 0): 1 1 0 0 0 0 0 0 0 0 -1
Note that the space group symmetry has 26 symmetry elements as it includes additional screw axis (`2_1`, `3_1`, `3_2`, `4_1`, `4_2`, `4_3`, `6_1`, `6_2`, `6_3, `6_4`, `6_5`) and glide plane (`a`, `b`, `c`, `d`, `n`) operations.
40 changes: 34 additions & 6 deletions pyxtal/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,15 +438,25 @@ def clean_structures(self, dtol=1e-3, etol=1e-3):
print("The following structures were deleted", to_delete)
self.db.delete(to_delete)

def clean_structures_pmg(self, dtol=5e-2, criteria=None, max_sim=None):
def clean_structures_pmg(self, dtol=5e-2, criteria=None):
"""
Clean up the db by removing the duplicate structures
Here we check the follow criteria
- same density
- pymatgen check
criteria should look like the following,
{'CN': {'C': 3},
'cutoff': 1.8,
'MAX_energy': -8.00,
#'MAX_similarity': 0.2,
'BAD_topology': ['hcb'],
'BAD_dimension': [0, 2],
}
Args:
dtol (float): tolerance of density
criteria (dict): including
"""

unique_rows = []
Expand All @@ -460,10 +470,29 @@ def clean_structures_pmg(self, dtol=5e-2, criteria=None, max_sim=None):
if not xtal.check_validity(criteria, True):
unique = False
print('Found unsatisfied criteria', row.id, row.space_group_number, row.wps)
if max_sim is not None:
if hasattr(row, 'similarity') and row.similarity > max_sim:
unique = False
print('Found unsatisfied similarity', row.id, row.similarity, row.space_group_number, row.wps)

if unique:
if 'MAX_energy' in criteria and hasattr(row, 'ff_energy') \
and row.ff_energy > criteria['MAX_energy']:
unique = False
print('Found unsatisfied energy', row.id, row.ff_energy, row.space_group_number, row.wps)
if unique:
if 'MAX_similarity' in criteria and hasattr(row, 'similarity') \
and row.similarity > criteria['MAX_similarity']:
unique = False
print('Found unsatisfied similarity', row.id, row.similarity, row.space_group_number, row.wps)
if unique:
if 'BAD_topology' in criteria and hasattr(row, 'topology') \
and row.topology[:3] in criteria['BAD_topology']:
unique = False
print('Found unsatisfied topology', row.id, row.topology, row.space_group_number, row.wps)
if unique:
if 'BAD_dimension' in criteria and hasattr(row, 'dimension') \
and row.dimension in criteria['BAD_dimension']:
unique = False
print('Found unsatisfied dimension', row.id, row.topology, row.space_group_number, row.wps)


if unique:
for prop in unique_rows:
(rowid, den) = prop
Expand All @@ -482,7 +511,6 @@ def clean_structures_pmg(self, dtol=5e-2, criteria=None, max_sim=None):
self.db.delete(to_delete)



def update_row_topology(self, StructureType='Auto', overwrite=True):
"""
Update row topology base on the CrystalNets.jl
Expand Down
62 changes: 38 additions & 24 deletions pyxtal/symmetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,34 @@ def list_wyckoff_combinations(self, numIons, quick=False, numWp=(None, None), Nm

return combinations, has_freedom, indices

def get_spg_symmetry_object(self):
"""
Generate the symmetry table for the given space group
It only supports space group now!
"""

if self.dim == 3:
l_type, bravis = self.lattice_type, self.symbol[0]
wp = self.get_wyckoff_position(0)

if 143 <= self.number <= 194:
ops = wp.get_euclidean_ops()
hexagonal = True
else:
ops = wp.ops

if bravis in ['A', 'B', 'C', 'I']:
ops = ops[:int(len(ops)/2)]
elif bravis == 'R':
ops = ops[:int(len(ops)/3)]
elif bravis == 'F':
ops = ops[:int(len(ops)/4)]

return site_symmetry(ops, l_type, bravis, True)
#ss.to_beautiful_matrix_representation()
else:
raise ValueError("Only supports space group symmetry")

def get_wyckoff_position(self, index):
"""
Returns a single Wyckoff_position object.
Expand Down Expand Up @@ -2894,7 +2922,7 @@ def set_table(self, skip=False):
if num_symmetries > 0:
strs = '{:4d} ({:2d} {:2d} {:2d}): '.format(direction_id, *axis)
for sym in matrix[i]:
strs +="{:4d}".format(sym)
strs +="{:4d} ".format(sym)
#strs += "{:4d}{:4d}{:4d}{:4d}{:4d}{:4d}{:4d}{:4d}{:4d}{:4d}".format(*matrix[i])
if not self.parse_trans:
symbol, _ = self.get_highest_symmetry(matrix[i])
Expand Down Expand Up @@ -3101,7 +3129,7 @@ def to_beautiful_matrix_representation(self, skip=True):
symbols = ['1', '-1', '2', 'm', '3', '4', '-4', '-3', '6', '-6']

for symbol in symbols:
strs += '{:4s}'.format(symbol)
strs += '{:<4s} '.format(symbol)
print(strs)
if not hasattr(self, 'table'): self.set_table(skip)
for row in self.table:
Expand Down Expand Up @@ -4070,45 +4098,31 @@ def get_symmetry_directions(lattice_type, symbol='P', unique_axis='b'):

if __name__ == "__main__":
print("Test pyxtal.wp.site symmetry")
for i in [14, 36, 62, 99, 143, 160, 182, 191, 225, 230]:
spg_list = [14, 36, 62, 99, 143, 160, 182, 191, 225, 230]
for i in spg_list:
g = Group(i)
for wp in g:
wp.get_site_symmetry()
print("{:4d} {:10s} {:10s}".format(wp.number, wp.get_label(), wp.site_symm))

print("Test pyxtal.wp.site symmetry representation")
for i in range(1, 231): #[14, 36, 62, 99, 143, 160, 182, 191, 225, 230]:
for i in spg_list:
g = Group(i)
for wp in g:
#ss = site_symmetry(wp.get_site_symm_ops(), g.lattice_type, g.symbol[0])
if wp.index > 0:
for idx in range(1): #wp.multiplicity):
ss = wp.get_site_symmetry_object(idx)
print('\n{:4d} {:10s} {:10s}'.format(wp.number, wp.get_label(), ss.name), ss.hm_symbols)
#ss.to_beautiful_matrix_representation(skip=True)
#print(ss.to_matrix_representation())
#print(ss.to_one_hot())
#if ss.name == '1':
# print("Problem exit")

print("Test pyxtal.wp.site space group")
for i in range(1, 231):
for i in spg_list:
g = Group(i)
print('\n', g.number, g.symbol)
wp = g[0]
if 143 <= i <= 194:
ops = wp.get_euclidean_ops()
hexagonal = True
else:
ops = wp.ops
hexagonal = False

if g.symbol[0] in ['A', 'B', 'C', 'I']:
ops = ops[:int(len(ops)/2)]
elif g.symbol[0] == 'R':
ops = ops[:int(len(ops)/3)]
elif g.symbol[0] == 'F':
ops = ops[:int(len(ops)/4)]

ss = site_symmetry(ops, g.lattice_type, g.symbol[0], True)
ss = g.get_spg_symmetry_object()
ss.to_beautiful_matrix_representation()
#matrix = ss.to_matrix_representation_spg()
#print(matrix)
#print(sum(sum(matrix)))
9 changes: 9 additions & 0 deletions pyxtal/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ def test_print_group_and_dof(self):
dof = g.get_lattice_dof()
self.assertTrue(dof == dof_ref)

def test_get_spg_symmetry_object(self):
spg_list = [14, 36, 62, 99, 143, 160, 182, 191, 225, 230]
ans = [32, 18, 36, 21, 16, 19, 24, 48, 62, 62]
for spg, num in zip(spg_list, ans):
g = Group(spg)
ss = g.get_spg_symmetry_object()
matrix = ss.to_matrix_representation_spg()
self.assertTrue(num == sum(sum(matrix)))

def test_short_path(self):
g = Group(217)
path = g.short_path_to_general_wp(7)
Expand Down

0 comments on commit 5de65f5

Please sign in to comment.