1010import numpy as np
1111from fractions import Fraction
1212from sympy import Eq , solve , Matrix , symbols , sympify
13+ import os
1314
1415a , b , g = symbols ('a b g' )
1516
@@ -37,19 +38,20 @@ def parse_expression_string(expr_string):
3738 return sympy_expressions
3839
3940
40- def transform_spg_ops_to_matrix (spg_ops ):
41+ def transform_spg_ops_to_matrix (spg_ops , syms ):
4142 '''Transforming space group operators in the string form into a matrix.
4243
4344 Args:
4445 spg_ops (list): A list of operators list like ["-x + y + 1/2", "-x", "z"]
46+ syms (list): A list of symbols corresponding to the operators
4547
4648 Returns:
4749 numpy.ndarray: A numpy array of space group operator matrices.
4850 '''
4951 base_vectors = {
50- 'x' : [1 , 0 , 0 ],
51- 'y' : [0 , 1 , 0 ],
52- 'z' : [0 , 0 , 1 ],
52+ syms [ 0 ] : [1 , 0 , 0 ],
53+ syms [ 1 ] : [0 , 1 , 0 ],
54+ syms [ 2 ] : [0 , 0 , 1 ],
5355 }
5456
5557 matrices = []
@@ -60,15 +62,15 @@ def parse_element(element):
6062 terms = re .split ('(?=[+-])' , element )
6163
6264 for term in terms :
63- if 'x' in term :
65+ if syms [ 0 ] in term :
6466 sign = - 1 if term .startswith ('-' ) else 1
65- resulatt_type_vector = [rv + sign * bv for rv , bv in zip (resulatt_type_vector , base_vectors ['x' ])]
66- elif 'y' in term :
67+ resulatt_type_vector = [rv + sign * bv for rv , bv in zip (resulatt_type_vector , base_vectors [syms [ 0 ] ])]
68+ elif syms [ 1 ] in term :
6769 sign = - 1 if term .startswith ('-' ) else 1
68- resulatt_type_vector = [rv + sign * bv for rv , bv in zip (resulatt_type_vector , base_vectors ['y' ])]
69- elif 'z' in term :
70+ resulatt_type_vector = [rv + sign * bv for rv , bv in zip (resulatt_type_vector , base_vectors [syms [ 1 ] ])]
71+ elif syms [ 2 ] in term :
7072 sign = - 1 if term .startswith ('-' ) else 1
71- resulatt_type_vector = [rv + sign * bv for rv , bv in zip (resulatt_type_vector , base_vectors ['z' ])]
73+ resulatt_type_vector = [rv + sign * bv for rv , bv in zip (resulatt_type_vector , base_vectors [syms [ 2 ] ])]
7274
7375 return resulatt_type_vector
7476
@@ -124,7 +126,8 @@ def grab_user_conv_transform(trans_str):
124126
125127 op_str = [[x_op , y_op , z_op ]]
126128
127- user_to_conv = transform_spg_ops_to_matrix (op_str )[0 ]
129+ syms = ['a' , 'b' , 'c' ]
130+ user_to_conv = transform_spg_ops_to_matrix (op_str , syms )[0 ]
128131
129132 return user_to_conv
130133
@@ -209,14 +212,26 @@ def solve_kvec_params(numkvec, kform):
209212
210213 Args:
211214 numkvec (list): k vector
212- kform (list ): Candidate k vector form
215+ kform (numpy array ): Candidate k vector form
213216
214217 Returns:
215218 list or dict: Solution for parameters involved in the provided k vector form.
216219 If a solution is found, the return will be a dictionary with parameter names as keys and their
217220 corresponding values as dict values. If no solution is found, an empty list is returned.
218221 """
222+ # Convert to sympy Matrix
219223 kform_m = Matrix (kform )
224+
225+ # Check if kform contains only numbers
226+ if not kform_m .free_symbols :
227+ # Perform a piecewise comparison
228+ kform_f = [float (f ) for f in kform ]
229+ if all (n == f for n , f in zip (numkvec , kform_f )):
230+ return {'match' : True }
231+ else :
232+ return {'match' : False }
233+
234+ # If kform contains symbols, solve for the parameters
220235 kvars = list (kform_m .free_symbols )
221236 kequats = [Eq (kform_m [i ] - n , 0 ) for i , n in enumerate (numkvec )]
222237 ksols = solve (kequats , kvars )
@@ -237,11 +252,15 @@ def find_kvec_form_param(spg_num, isocif_cif, k_vec, k_forms):
237252 Returns:
238253 tuple: (index of k_form, a, b, g)
239254 """
240- with open ("./sgtables.json" , "r" ) as f :
255+ script_path = os .path .dirname (os .path .abspath (__file__ ))
256+ with open (os .path .join (script_path , "sgtables.json" ), "r" ) as f :
241257 sgtables = json .load (f )
242258
243259 spg_sym = sgtables [str (spg_num )]["SPGSym" ]
244- user_aff_ops = transform_spg_ops_to_matrix (sgtables [str (spg_num )]["SPGOps" ])
260+ user_aff_ops = transform_spg_ops_to_matrix (
261+ sgtables [str (spg_num )]["SPGOps" ],
262+ syms = ['x' , 'y' , 'z' ]
263+ )
245264
246265 user_to_ref_conv_p_l = grab_user_conv_line (isocif_cif )
247266 user_to_ref_conv_p = grab_user_conv_transform (user_to_ref_conv_p_l )
@@ -256,7 +275,11 @@ def find_kvec_form_param(spg_num, isocif_cif, k_vec, k_forms):
256275 ref_pt_ops = np .matmul (user_to_ref_pr_q , np .matmul (user_aff_ops , user_to_ref_pr_p ))
257276
258277 k_vec_pr = np .dot (np .array (k_vec ), user_to_ref_pr_p [0 :3 , 0 :3 ])
259- k_forms_pr = np .matmul (k_forms , user_to_ref_pr_p [0 :3 , 0 :3 ])
278+ k_forms_tmp = []
279+ for k_form_t in k_forms :
280+ k_forms_tmp .append (k_form_t [1 ])
281+ k_forms_tmp = np .array (k_forms_tmp )
282+ k_forms_pr = np .matmul (k_forms_tmp , user_to_ref_pr_p [0 :3 , 0 :3 ])
260283
261284 def sort_keys (dict_entry ):
262285 # Sort keys by priority: a, then b, then g
@@ -268,7 +291,7 @@ def sort_keys(dict_entry):
268291 for arm in k_vec_pr_arms :
269292 arm_sols = []
270293 for k_form in k_forms_pr :
271- sol = solve_kvec_params (arm , k_form )
294+ sol = solve_kvec_params (arm [: 3 ] , k_form )
272295 if sol :
273296 arm_sols .append (sol )
274297 else :
@@ -280,7 +303,10 @@ def sort_keys(dict_entry):
280303
281304 for i , entry in enumerate (arm_sols ):
282305 if isinstance (entry , dict ):
283- num_keys = len (entry )
306+ if 'match' in entry and entry ['match' ] is True :
307+ num_keys = 0
308+ else :
309+ num_keys = len (entry )
284310
285311 # Compare this entry to the current best entry
286312 if num_keys < min_keys or (num_keys == min_keys and sort_keys (entry ) < sort_keys (best_dict )):
0 commit comments