@@ -160,6 +160,8 @@ def __init__(self, ensemble = None, root_representation = "normal",
160160
161161 self .minimizer = None #
162162
163+ self .max_diag_error_counter = __MAX_DIAG_ERROR_COUNTER__
164+
163165 # Projection. This is chosen to fix some constraint on the minimization
164166 self .projector_dyn = None
165167 self .projector_struct = None
@@ -190,6 +192,9 @@ def __init__(self, ensemble = None, root_representation = "normal",
190192 # If true use spglib to impose symmetries
191193 # NOTE: It is slower, but it enables using supercells
192194 self .use_spglib = False
195+
196+ # If True, enforce the symmetrization and the sum rule after each step
197+ self .enforce_sum_rule = False
193198
194199
195200 # Setup the statistical threshold
@@ -461,32 +466,41 @@ def minimization_step(self, custom_function_gradient = None):
461466 if self .minim_struct :
462467 self .dyn .structure .coords [:,:] = new_struct
463468
469+ # Check if we must enforce the symmetries and the sum rule:
470+ if self .enforce_sum_rule and (not self .neglect_symmetries ):
471+ self .dyn .Symmetrize (use_spglib = self .use_spglib )
472+
473+
464474 # If we have imaginary frequencies, force the kl ratio to zero
465475 if self .check_imaginary_frequencies ():
466476 print ("Immaginary frequencies found! Redoing the step." )
467477 new_kl_ratio = 0
468478 is_diag_ok = False
469-
470-
471- # Update the ensemble
472- try :
473- self .update ()
474- except np .linalg .LinAlgError as error :
475- print ("Diagonalization error:" )
476- print (error )
477- print ("Reducing the minimization step..." )
478- new_kl_ratio = 0 # Force step reduction
479- is_diag_ok = False
480- diag_error_counter += 1
481-
482- if diag_error_counter >= __MAX_DIAG_ERROR_COUNTER__ :
479+ diag_error_counter += 1
480+ else :
481+ # Update the ensemble
482+ try :
483+ self .update ()
484+ except np .linalg .LinAlgError as error :
485+ print ("Diagonalization error:" )
486+ print (error )
487+ print ("Reducing the minimization step..." )
488+ new_kl_ratio = 0 # Force step reduction
489+ is_diag_ok = False
490+ diag_error_counter += 1
491+
492+ if diag_error_counter >= self . max_diag_error_counter :
483493 ERROR_MSG = """
484- Error, exceeded the maximum number of diagonalization error.
485- something is very wrong with the dynamical matrix.
494+ Error, exceeded the maximum number of diagonalization error. (or imaginary steps)
495+
496+ you can get rid of this error by increasing max_diag_error_counter variable.
497+
498+ Something is very wrong with the dynamical matrix.
486499 I'm saving the dynamical matrix as error_dyn,
487500 if you want to check it or restart the calculation from there.
488501"""
489502 print (ERROR_MSG )
503+ sys .stdout .flush ()
490504 self .dyn .save_qe ("error_dyn" )
491505 raise ValueError (ERROR_MSG )
492506
@@ -1227,11 +1241,14 @@ def check_imaginary_frequencies(self):
12271241 """
12281242
12291243 # Get the frequencies
1230- superdyn = self .dyn .GenerateSupercellDyn (self .ensemble .supercell )
1231- w , pols = superdyn .DyagDinQ (0 )
1244+ #superdyn = self.dyn.GenerateSupercellDyn(self.ensemble.supercell)
1245+ w , pols = self .dyn .DiagonalizeSupercell ()#.DyagDinQ(0)
1246+ ss = self .dyn .structure .generate_supercell (self .dyn .GetSupercell ())
12321247
12331248 # Get translations
1234- trans_mask = ~ CC .Methods .get_translations (pols , superdyn .structure .get_masses_array ())
1249+ trans_mask = ~ CC .Methods .get_translations (pols , ss .get_masses_array ())
1250+
1251+ current_n_trans = np .sum ((~ trans_mask ).astype (int ))
12351252
12361253 # Remove translations
12371254 w = w [trans_mask ]
@@ -1240,10 +1257,30 @@ def check_imaginary_frequencies(self):
12401257 # Frequencies are ordered, check if the first one is negative.
12411258 if w [0 ] < 0 :
12421259 print ("Total frequencies (excluding translations):" )
1243- superdyn0 = self .ensemble .dyn_0 .GenerateSupercellDyn (self .ensemble .supercell )
1244- wold , pold = superdyn0 .DyagDinQ (0 )
1260+ #superdyn0 = self.ensemble.dyn_0.GenerateSupercellDyn(self.ensemble.supercell)
1261+ wold , pold = self .ensemble .dyn_0 .DiagonalizeSupercell ()# superdyn0.DyagDinQ(0)
1262+
1263+ ss0 = self .ensemble .dyn_0 .structure .generate_supercell (self .dyn .GetSupercell ())
12451264
1246- trans_mask = ~ CC .Methods .get_translations (pold , superdyn0 .structure .get_masses_array ())
1265+ trans_mask = ~ CC .Methods .get_translations (pold , ss0 .get_masses_array ())
1266+
1267+ old_n_trans = np .sum ((~ trans_mask ).astype (int ))
1268+
1269+ if old_n_trans != current_n_trans :
1270+ ERR_MSG = """
1271+ Error, the number of translational modes before and after the step is different.
1272+ original translational modes: {}
1273+ new translational modes: {}
1274+
1275+ You can try to fix this error setting the {} variable of {} class to True.
1276+ """ .format (old_n_trans , current_n_trans , "enforce_sum_rule" , self .__class__ .__name__ )
1277+ print (ERR_MSG )
1278+ if not self .enforce_sum_rule :
1279+ raise ValueError (ERR_MSG )
1280+ else :
1281+ return True
1282+
1283+
12471284 wold = wold [trans_mask ] * __RyToCm__
12481285 pold = pold [:, trans_mask ]
12491286 total_mask = list (range (len (w )))
0 commit comments