Skip to content

Commit 4a5beb4

Browse files
committed
A faster code when the diagonalization is the bottleneck
1 parent 751d238 commit 4a5beb4

1 file changed

Lines changed: 25 additions & 14 deletions

File tree

Modules/Ensemble.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,15 +1178,15 @@ def update_weights(self, new_dynamical_matrix, newT, update_q = False):
11781178
super_struct0 = self.dyn_0.structure.generate_supercell(self.supercell)
11791179
#super_dyn = self.dyn_0.GenerateSupercellDyn(self.supercell)
11801180

1181-
w, pols = self.dyn_0.DiagonalizeSupercell()#super_dyn.DyagDinQ(0)
1181+
w_original, pols_original = self.dyn_0.DiagonalizeSupercell()#super_dyn.DyagDinQ(0)
11821182

11831183
# Exclude translations
11841184
if not self.ignore_small_w:
1185-
trans_original = CC.Methods.get_translations(pols, super_struct0.get_masses_array())
1185+
trans_original = CC.Methods.get_translations(pols_original, super_struct0.get_masses_array())
11861186
else:
11871187
trans_original = np.abs(w) < CC.Phonons.__EPSILON_W__
11881188

1189-
w = w[~trans_original]
1189+
w = w_original[~trans_original]
11901190

11911191
# Convert from Ry to Ha and in fortran double precision
11921192
w = np.array(w/2, dtype = np.float64)
@@ -1198,12 +1198,12 @@ def update_weights(self, new_dynamical_matrix, newT, update_q = False):
11981198
super_structure = new_dynamical_matrix.structure.generate_supercell(self.supercell)
11991199
#new_super_dyn = new_dynamical_matrix.GenerateSupercellDyn(self.supercell)
12001200

1201-
w, pols = new_dynamical_matrix.DiagonalizeSupercell()#new_super_dyn.DyagDinQ(0)
1201+
w_new, pols = new_dynamical_matrix.DiagonalizeSupercell()#new_super_dyn.DyagDinQ(0)
12021202

12031203
if not self.ignore_small_w:
12041204
trans_mask = CC.Methods.get_translations(pols, super_structure.get_masses_array())
12051205
else:
1206-
trans_mask = np.abs(w) < CC.Phonons.__EPSILON_W__
1206+
trans_mask = np.abs(w_new) < CC.Phonons.__EPSILON_W__
12071207

12081208

12091209
# Check if the new dynamical matrix satisfies the sum rule
@@ -1230,7 +1230,7 @@ def update_weights(self, new_dynamical_matrix, newT, update_q = False):
12301230
print(ERR_MSG)
12311231
raise ValueError(ERR_MSG)
12321232

1233-
w = w[~trans_mask]
1233+
w= w_new[~trans_mask]
12341234
w = np.array(w/2, dtype = np.float64)
12351235
new_a = SCHAModules.thermodynamic.w_to_a(w, newT)
12361236

@@ -1249,7 +1249,7 @@ def update_weights(self, new_dynamical_matrix, newT, update_q = False):
12491249
# old_disps[i,:] = (self.xats[i, :, :] - super_dyn.structure.coords).reshape( 3*Nat_sc )
12501250

12511251
# # TODO: this method recomputes the displacements, it is useless since we already have them in self.u_disps
1252-
self.sscha_energies[:], self.sscha_forces[:,:,:] = new_dynamical_matrix.get_energy_forces(None, displacement = self.u_disps)
1252+
self.sscha_energies[:], self.sscha_forces[:,:,:] = new_dynamical_matrix.get_energy_forces(None, displacement = self.u_disps, w_pols = (w_new, pols))
12531253

12541254
t4 = time.time()
12551255

@@ -1271,8 +1271,8 @@ def update_weights(self, new_dynamical_matrix, newT, update_q = False):
12711271

12721272

12731273
# Get the covariance matrices of the ensemble
1274-
ups_new = np.real(new_dynamical_matrix.GetUpsilonMatrix(self.current_T))
1275-
ups_old = np.real(self.dyn_0.GetUpsilonMatrix(self.T0))
1274+
ups_new = np.real(new_dynamical_matrix.GetUpsilonMatrix(self.current_T, w_pols = (w_new, pols)))
1275+
ups_old = np.real(self.dyn_0.GetUpsilonMatrix(self.T0, w_pols = (w_original, pols_original)))
12761276

12771277
# Get the normalization ratio
12781278
#norm = np.sqrt(np.abs(np.linalg.det(ups_new) / np.linalg.det(ups_old)))
@@ -1755,11 +1755,22 @@ def get_preconditioned_gradient(self, subtract_sscha = True, return_error = Fals
17551755
if verbose:
17561756
print (" [GRADIENT] Time to call the fortran code:", t2 - t1, "s")
17571757

1758-
# Perform the fourier transform
1759-
q_grad = CC.Phonons.GetDynQFromFCSupercell(grad, np.array(self.current_dyn.q_tot),
1760-
self.current_dyn.structure, supercell_dyn.structure)
1761-
q_grad_err = CC.Phonons.GetDynQFromFCSupercell(grad_err, np.array(self.current_dyn.q_tot),
1762-
self.current_dyn.structure, supercell_dyn.structure)
1758+
# If we are at gamma, we can skip this part
1759+
# Which makes the code faster
1760+
if np.prod(self.dyn_0.GetSupercell()) > 1:
1761+
1762+
# Perform the fourier transform
1763+
q_grad = CC.Phonons.GetDynQFromFCSupercell(grad, np.array(self.current_dyn.q_tot),
1764+
self.current_dyn.structure, supercell_dyn.structure)
1765+
q_grad_err = CC.Phonons.GetDynQFromFCSupercell(grad_err, np.array(self.current_dyn.q_tot),
1766+
self.current_dyn.structure, supercell_dyn.structure)
1767+
else:
1768+
nat3, _ = grad.shape
1769+
q_grad = np.zeros( (1, nat3, nat3), dtype = np.double)
1770+
q_grad_err = np.zeros_like(q_grad)
1771+
q_grad[0, :, :] = grad
1772+
q_grad_err[0, :, :] = grad_err
1773+
17631774
t1 = time.time()
17641775
if verbose:
17651776
print (" [GRADIENT] Time to get back in fourier space:", t1 - t2, "s")

0 commit comments

Comments
 (0)