Skip to content

Commit abd83d5

Browse files
committed
Code cleanup
1 parent 36fe56a commit abd83d5

File tree

5 files changed

+79
-74
lines changed

5 files changed

+79
-74
lines changed

abipy/dfpt/qha_2D.py

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,9 @@ def from_json_file(cls,
4343
For the meaning of the other arguments see from_gsr_ddb_paths.
4444
"""
4545
data = mjson_load(filepath)
46-
47-
bo_strains_ac = [data["strains_a"], data["strains_c"]]
48-
phdos_strains_ac = [data["strains_a"], data["strains_c"]]
49-
5046
return cls.from_gsr_ddb_paths(nqsmall_or_qppa,
5147
data["gsr_relax_paths"], data["ddb_relax_paths"],
52-
bo_strains_ac, phdos_strains_ac,
48+
data["bo_strains_ac"], data["phdos_strains_ac"],
5349
anaget_kwargs=anaget_kwargs, smearing_ev=smearing_ev, verbose=verbose)
5450

5551
@classmethod
@@ -203,8 +199,8 @@ def plot_energies(self, ax=None, **kwargs) -> Figure:
203199
ax, fig, plt = get_ax_fig_plt(ax, figsize=(10, 8))
204200
ax = fig.add_subplot(111, projection='3d') # Create a 3D subplot
205201

206-
a0 =self.lattice_a[:,0]
207-
c0 =self.lattice_c[0,:]
202+
a0 = self.lattice_a[:,0]
203+
c0 = self.lattice_c[0,:]
208204

209205
X, Y = np.meshgrid(c0, a0)
210206

@@ -216,7 +212,7 @@ def plot_energies(self, ax=None, **kwargs) -> Figure:
216212

217213
initial_guess = [1.005*self.lattice_a[self.ix0,0], 1.005*self.lattice_c[0,self.iy0]]
218214
xy_init = np.array(initial_guess)
219-
min_x0,min_y0,min_energy= self.find_minimum( f_interp, xy_init, tol=1e-6, max_iter=1000, step_size=0.01)
215+
min_x0, min_y0, min_energy= self.find_minimum( f_interp, xy_init, tol=1e-6, max_iter=1000, step_size=0.01)
220216

221217
x_new = np.linspace(min(self.lattice_a[:,0]), max(self.lattice_a[:,0]), 100)
222218
y_new = np.linspace(min(self.lattice_c[0,:]), max(self.lattice_c[0,:]), 100)
@@ -227,10 +223,10 @@ def plot_energies(self, ax=None, **kwargs) -> Figure:
227223
ax.plot_surface(x_grid, y_grid, energy_interp, cmap='viridis', alpha=0.6)
228224

229225
# Set labels
230-
ax.set_xlabel('Lattice Parameter C (Å)')
231-
ax.set_ylabel('Lattice Parameter A (Å)')
226+
ax.set_xlabel('Lattice parameter C (Å)')
227+
ax.set_ylabel('Lattice parameter A (Å)')
232228
ax.set_zlabel('Energy (eV)')
233-
ax.set_title('Energy Surface in 3D')
229+
ax.set_title('BO Energy Surface in 3D')
234230

235231
return fig
236232

@@ -266,7 +262,7 @@ def find_minimum(self, f_interp, xy_init, tol=1e-6, max_iter=1000, step_size=0.0
266262
return xy[0], xy[1], min_energy
267263

268264
@add_fig_kwargs
269-
def plot_free_energies(self, tstart=800 , tstop=0 ,num=5, ax=None, **kwargs) -> Figure:
265+
def plot_free_energies(self, tstart=800, tstop=0, num=5, ax=None, **kwargs) -> Figure:
270266
"""
271267
Plot free energy as a function of temperature in a 3D plot.
272268
@@ -286,8 +282,8 @@ def plot_free_energies(self, tstart=800 , tstop=0 ,num=5, ax=None, **kwargs) ->
286282

287283
X, Y = np.meshgrid(self.lattice_c[0,:], self.lattice_a[:,0])
288284
for e in ( tot_en.T ):
289-
ax.plot_surface(X, Y ,e, cmap='viridis', alpha=0.7)
290-
ax.plot_wireframe(X, Y ,e, cmap='viridis')
285+
ax.plot_surface(X, Y, e, cmap='viridis', alpha=0.7)
286+
ax.plot_wireframe(X, Y, e, cmap='viridis')
291287

292288
min_x = np.zeros(num)
293289
min_y = np.zeros(num)
@@ -336,23 +332,23 @@ def plot_free_energies(self, tstart=800 , tstop=0 ,num=5, ax=None, **kwargs) ->
336332
initial_guess = [1.005*self.lattice_a[self.ix0,0], 1.005*self.lattice_c[0,self.iy0]]
337333
xy_init = np.array(initial_guess)
338334
for j, e in enumerate(tot_en2.T):
339-
f_interp = RectBivariateSpline(a,c, e , kx=4, ky=4)
340-
min_x[j],min_y[j],min_tot_en2[j]= self.find_minimum( f_interp, xy_init, tol=1e-6, max_iter=1000, step_size=0.01)
335+
f_interp = RectBivariateSpline(a, c, e, kx=4, ky=4)
336+
min_x[j],min_y[j],min_tot_en2[j] = self.find_minimum(f_interp, xy_init, tol=1e-6, max_iter=1000, step_size=0.01)
341337

342338
X, Y = np.meshgrid(c, a)
343339
for e in tot_en2.T:
344340
ax.plot_wireframe(X, Y, e, cmap='viridis')
345-
ax.plot_surface(X, Y ,e, cmap='viridis', alpha=0.7)
341+
ax.plot_surface(X, Y, e, cmap='viridis', alpha=0.7)
346342

347-
ax.scatter(min_y,min_x,min_tot_en2, color='c', s=100)
348-
ax.plot(min_y,min_x,min_tot_en2, color='c')
343+
ax.scatter(min_y, min_x, min_tot_en2, color='c', s=100)
344+
ax.plot(min_y, min_x, min_tot_en2, color='c')
349345

350346
ax.scatter(self.lattice_c[0,self.iy0], self.lattice_a[self.ix0,0], self.energies[self.ix0, self.iy0], color='red', s=100)
351347

352348
ax.set_xlabel('C')
353349
ax.set_ylabel('A')
354-
ax.set_zlabel('Energy (eV)')
355-
#ax.set_title('Energies as a 3D Plot')
350+
ax.set_zlabel('Free energy (eV)')
351+
#ax.set_title('Free energies as a 3D Plot')
356352
plt.savefig("energy.pdf", format="pdf", bbox_inches="tight")
357353

358354
return fig
@@ -403,11 +399,11 @@ def plot_thermal_expansion(self, tstart=800, tstop=0, num=81, ax=None, **kwargs)
403399

404400
elif (len(self.lattice_a_from_phdos)==3 or len(self.lattice_c_from_phdos)==3):
405401

406-
dF_dA = np.zeros( num)
407-
dF_dC = np.zeros( num)
408-
d2F_dA2= np.zeros( num)
409-
d2F_dC2= np.zeros( num)
410-
d2F_dAdC = np.zeros( num)
402+
dF_dA = np.zeros(num)
403+
dF_dC = np.zeros(num)
404+
d2F_dA2 = np.zeros(num)
405+
d2F_dC2 = np.zeros(num)
406+
d2F_dAdC = np.zeros(num)
411407
a0 = self.lattice_a_from_phdos[1,1]
412408
c0 = self.lattice_c_from_phdos[1,1]
413409
da = self.lattice_a_from_phdos[0,1]-self.lattice_a_from_phdos[1,1]
@@ -436,7 +432,7 @@ def plot_thermal_expansion(self, tstart=800, tstop=0, num=81, ax=None, **kwargs)
436432
A0 = self.lattice_a[self.ix0,self.iy0]
437433
C0 = self.lattice_c[self.ix0,self.iy0]
438434
scale= self.volumes[self.ix0,self.iy0]/A0**2/C0
439-
min_v=min_x**2*min_y*scale
435+
min_v = min_x**2*min_y*scale
440436

441437
dt = tmesh[1] - tmesh[0]
442438
alpha_a = (min_x[2:] - min_x[:-2]) / (2 * dt) / min_x[1:-1]
@@ -447,9 +443,10 @@ def plot_thermal_expansion(self, tstart=800, tstop=0, num=81, ax=None, **kwargs)
447443
#ax.plot(tmesh[1:-1], alpha_v, linestyle='--', color='darkorange', label=r"$\alpha_v$ E$\infty$Vib2")
448444

449445
# Save the data
450-
data_to_save = np.column_stack((tmesh[1:-1],alpha_v,alpha_a,alpha_c))
451-
columns= [ '#Tmesh', 'alpha_v' , 'alpha_a', 'alpha_c']
446+
data_to_save = np.column_stack((tmesh[1:-1], alpha_v, alpha_a, alpha_c))
447+
columns = ['#Tmesh', 'alpha_v', 'alpha_a', 'alpha_c']
452448
file_path = 'thermal-expansion_data.txt'
449+
print(f"Writing thermal expansion data to: {file_path}"
453450
np.savetxt(file_path, data_to_save, fmt='%4.6e', delimiter='\t\t', header='\t\t\t'.join(columns), comments='')
454451

455452
ax.grid(True)
@@ -533,7 +530,7 @@ def plot_lattice(self, tstart=800, tstop=0, num=81, ax=None, **kwargs) -> Figure
533530

534531
A0 = self.lattice_a[self.ix0,self.iy0]
535532
C0 = self.lattice_c[self.ix0,self.iy0]
536-
scale= self.volumes[self.ix0,self.iy0]/A0**2/C0
533+
scale = self.volumes[self.ix0,self.iy0]/A0**2/C0
537534
min_volumes = min_x**2 * min_y * scale
538535

539536
axs[0].plot(tmesh, min_x, color='c', label=r"$a$ (E$\infty$Vib2)", linewidth=2)
@@ -571,9 +568,10 @@ def get_vib_free_energies(self, tstart: float, tstop: float, num: int) -> np.nda
571568
Return: A 3D array of vibrational free energies of shape (num_c, num_a, num_temp)
572569
"""
573570
f = np.zeros((len(self.lattice_c_from_phdos[0]), len(self.lattice_a_from_phdos[:, 0]), num))
571+
574572
for i in range(len(self.lattice_a_from_phdos[:, 0])):
575573
for j in range(len(self.lattice_c_from_phdos[0])):
576-
dos = self.phdoses[i][j]
577-
if dos is not None:
578-
f[j][i] = dos.get_free_energy(tstart, tstop, num).values
574+
phdos = self.phdoses[i][j]
575+
if phdos is not None:
576+
f[j][i] = phdos.get_free_energy(tstart, tstop, num).values
579577
return f

abipy/flowtk/flows.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ def _iflat_tasks_wti(self, status=None, op="==", nids=None, with_wti=True):
753753
else:
754754
yield task
755755

756-
def abivalidate_inputs(self) -> tuple:
756+
def abivalidate_inputs(self, verbose: int = 1) -> tuple:
757757
"""
758758
Run ABINIT in dry mode to validate all the inputs of the flow.
759759
@@ -777,7 +777,11 @@ def abivalidate_inputs(self) -> tuple:
777777
isok, tuples = True, []
778778
for task in self.iflat_tasks():
779779
t = task.input.abivalidate()
780-
if t.retcode != 0: isok = False
780+
if t.retcode != 0:
781+
isok = False
782+
if verbose:
783+
print(t.stderr_file.read())
784+
781785
tuples.append(t)
782786

783787
return isok, tuples

abipy/flowtk/qha_2d.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class Qha2dFlow(Flow):
2626
def from_scf_input(cls,
2727
workdir: PathLike,
2828
scf_input: AbinitInput,
29-
bo_strains_ac,
30-
phdos_strains_ac,
29+
bo_strains_ac: list[list],
30+
phdos_strains_ac: list[list]:,
3131
ngqpt,
3232
with_becs: bool,
3333
with_quad: bool,
@@ -67,10 +67,10 @@ def finalize(self):
6767
data = {"bo_strains_ac": work.bo_strains_ac, "phdos_strains_ac": work.phdos_strains_ac}
6868

6969
# Build list of strings with path to the relevant output files ordered by V.
70-
data["gsr_relax_paths"] = [task.gsr_path for task in work.relax_tasks_deformed]
70+
data["gsr_relax_paths"] = [task.gsr_path for task in work.relax_tasks_strained]
7171

7272
gsr_relax_entries, gsr_relax_volumes = [], []
73-
for task in work.relax_tasks_deformed:
73+
for task in work.relax_tasks_strained:
7474
with task.open_gsr() as gsr:
7575
gsr_relax_entries.append(dict(
7676
volume=gsr.structure.volume,
@@ -120,9 +120,9 @@ def from_scf_input(cls,
120120
# Save attributes in work
121121
work.initial_scf_input = scf_input
122122

123+
# Make sure ench row is a numpy array.
123124
work.bo_strains_ac = bo_strains_ac
124125
work.phdos_strains_ac = phdos_strains_ac
125-
# Make sure ench row is a numpy array.
126126
for i in range(2):
127127
work.bo_strains_ac[i] = np.array(bo_strains_ac[i])
128128
work.phdos_strains_ac[i] = np.array(phdos_strains_ac[i])
@@ -153,23 +153,23 @@ def on_ok(self, sender):
153153
# Get relaxed structure and build new task for structural relaxation at fixed volume.
154154
relaxed_structure = sender.get_final_structure()
155155

156-
relax_template = self.relax_template
157-
self.relax_tasks_deformed = []
156+
self.relax_tasks_strained = []
158157

159158
import itertools
160159
for s1, s3 in itertools.product(self.bo_strains_ac[0], self.bo_strains_ac[1]):
161-
deformation_name = f"{s1=}, {s3=}"
160+
strain_name = f"{s1=}, {s3=}"
162161
# Apply strain to the structure
163162
strain_tensor = np.diag([s1, s1, s3])
164163
strained_structure = relaxed_structure.apply_strain(strain_tensor, inplace=False)
165164
#print("strained_structure:", strained_structure)
166165

167166
# Relax deformed structure with fixed unit cell.
168-
task = self.register_relax_task(relax_template.new_with_structure(strained_structure, optcell=0))
167+
task = self.register_relax_task(self.relax_template.new_with_structure(strained_structure, optcell=0))
168+
169169
task.bo_strain = (s1, s3)
170170
task.in_phdos_strains = np.any(np.abs(s1 - self.phdos_strains_ac[0]) < 1e-3) and \
171171
np.any(np.abs(s3 - self.phdos_strains_ac[1]) < 1e-3)
172-
self.relax_tasks_deformed.append(task)
172+
self.relax_tasks_strained.append(task)
173173

174174
self.flow.allocate(build=True)
175175

@@ -185,9 +185,9 @@ def on_all_ok(self):
185185
# Build phonon works for the different relaxed structures.
186186
self.ph_works = []
187187

188-
for task in self.relax_tasks_deformed:
188+
for task in self.relax_tasks_strained:
189189
s1, s3 = task.bo_strain
190-
deformation_name = f"{s1=}, {s3=}"
190+
strain_name = f"{s1=}, {s3=}"
191191

192192
relaxed_structure = task.get_final_structure()
193193
scf_input = self.initial_scf_input.new_with_structure(relaxed_structure)
@@ -197,11 +197,10 @@ def on_all_ok(self):
197197
with_becs=self.with_becs, ddk_tolerance=None)
198198

199199
# Reduce the number of files produced in the DFPT tasks to avoid possible disk quota issues.
200-
prtvars = dict(prtden=0, prtpot=0)
201200
for task in ph_work[1:]:
202-
task.input.set_vars(**prtvars)
201+
task.input.set_vars(prtden=0, prtpot=0)
203202

204-
ph_work.set_name(deformation_name)
203+
ph_work.set_name(strain_name)
205204
self.ph_works.append(ph_work)
206205
self.flow.register_work(ph_work)
207206

abipy/flowtk/vzsisa.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,8 @@ def on_all_ok(self):
171171
ddk_tolerance=None)
172172

173173
# Reduce the number of files produced in the DFPT tasks to avoid possible disk quota issues.
174-
prtvars = dict(prtden=0, prtpot=0)
175174
for task in ph_work[1:]:
176-
task.input.set_vars(**prtvars)
175+
task.input.set_vars(prtden=0, prtpot=0)
177176

178177
self.flow.register_work(ph_work)
179178
self.ph_works.append(ph_work)

abipy/flowtk/zsisa.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ def finalize(self):
6464
data = {"eps": work.eps, "spgrp_number": work.spgrp_number}
6565

6666
# Build list of strings with path to the relevant output files ordered by V.
67-
data["gsr_relax_paths"] = [task.gsr_path for task in work.relax_tasks_deformed]
67+
data["gsr_relax_paths"] = [task.gsr_path for task in work.relax_tasks_strained]
6868
data["strain_inds"] = work.strain_inds
6969

7070
gsr_relax_entries, gsr_relax_volumes = [], []
71-
for task in work.relax_tasks_deformed:
71+
for task in work.relax_tasks_strained:
7272
with task.open_gsr() as gsr:
7373
gsr_relax_entries.append(dict(
7474
volume=gsr.structure.volume,
@@ -143,19 +143,13 @@ def on_ok(self, sender):
143143
# Get relaxed structure and build new task for structural relaxation at fixed volume.
144144
relaxed_structure = sender.get_final_structure()
145145

146-
self.deformed_structures_dict, self.strain_inds, self.spgrp_number = generate_deformations(relaxed_structure, self.eps)
146+
self.strained_structures_dict, self.strain_inds, self.spgrp_number = generate_deformations(relaxed_structure, self.eps)
147147

148-
relax_template = self.relax_template
149-
self.relax_tasks_deformed = []
150-
for structure in self.deformed_structures_dict.values():
148+
self.relax_tasks_strained = []
149+
for structure in self.strained_structures_dict.values():
151150
# Relax deformed structure with fixed unit cell.
152-
task = self.register_relax_task(relax_template.new_with_structure(structure, optcell=0))
153-
self.relax_tasks_deformed.append(task)
154-
155-
# Build work for elastic properties (clamped-ions)
156-
# activate internal strain and piezoelectric part.
157-
#from abipy.flowtk.dfpt import ElasticWork
158-
#elastic_work = ElasticWork.from_scf_input(scf_input, with_relaxed_ion=True, with_piezo=True)
151+
task = self.register_relax_task(self.relax_template.new_with_structure(structure, optcell=0))
152+
self.relax_tasks_strained.append(task)
159153

160154
self.flow.allocate(build=True)
161155

@@ -171,25 +165,24 @@ def on_all_ok(self):
171165
# Build phonon works for the different relaxed structures.
172166
self.ph_works = []
173167

174-
for task, deform_name in zip(self[1:], self.deformed_structures_dict.keys(), strict=True):
168+
for task, strain_name in zip(self[1:], self.strained_structures_dict.keys(), strict=True):
175169
relaxed_structure = task.get_final_structure()
176170
scf_input = self.initial_scf_input.new_with_structure(relaxed_structure)
177171
ph_work = PhononWork.from_scf_input(scf_input, self.ngqpt, is_ngqpt=True, tolerance=None,
178172
with_becs=self.with_becs, ddk_tolerance=None)
179173

180174
# Reduce the number of files produced in the DFPT tasks to avoid possible disk quota issues.
181-
prtvars = dict(prtden=0, prtpot=0)
182175
for task in ph_work[1:]:
183-
task.input.set_vars(**prtvars)
176+
task.input.set_vars(prtden=0, prtpot=0)
184177

185-
ph_work.set_name(deform_name)
178+
ph_work.set_name(strain_name)
186179
self.ph_works.append(ph_work)
187180
self.flow.register_work(ph_work)
188181

189182
# Add task for electron DOS calculation to edos_work
190183
if self.edos_ngkpt is not None:
191184
edos_input = scf_input.make_edos_input(self.edos_ngkpt)
192-
self.edos_work.register_nscf_task(edos_input, deps={ph_work[0]: "DEN"}).set_name(deform_name)
185+
self.edos_work.register_nscf_task(edos_input, deps={ph_work[0]: "DEN"}).set_name(strain_name)
193186

194187
if self.edos_ngkpt is not None:
195188
self.flow.register_work(self.edos_work)
@@ -227,6 +220,9 @@ def from_relax_input(cls,
227220
for pressure_gpa in work.pressures_gpa:
228221
for temperature in work.temperatures:
229222
#strtarget = zsisa.get_strtarget(temperature, pressure)
223+
#converged, new_structure, strtarget = zsisa.get_new_guess(relaxed_structure,
224+
# self.temperature, self.pressure_gpa, tolerance)
225+
230226
new_input = relax_input.new_with_vars(strtarget=strtarget)
231227
task = work.register_task(new_input, task_class=ThermalRelaxTask)
232228
# Attach pressure and temperature
@@ -239,6 +235,10 @@ def on_all_ok(self):
239235
"""
240236
Implement the post-processing step at the end of the Work.
241237
"""
238+
# Build work for elastic properties (clamped-ions)
239+
# activate internal strain and piezoelectric part.
240+
#from abipy.flowtk.dfpt import ElasticWork
241+
#elastic_work = ElasticWork.from_scf_input(scf_input, with_relaxed_ion=True, with_piezo=True)
242242
return super().on_all_ok()
243243

244244

@@ -248,10 +248,15 @@ def _on_ok(self):
248248
results = super()._on_ok()
249249
zsisa = self.work.zsisa
250250

251+
relaxed_structure = sender.get_final_structure()
252+
converged, new_structure, strtarget = zsisa.get_new_guess(relaxed_structure,
253+
self.temperature, self.pressure_gpa, tolerance)
254+
251255
# Check for convergence.
252-
#if not self.collinear_done:
253-
# self.input.set_vars(strtarget=strtarget)
254-
# self.finalized = False
255-
# self.restart()
256+
if not converged:
257+
#self.input.set_structure(new_structure)
258+
self.input.set_vars(strtarget=strtarget)
259+
self.finalized = False
260+
self.restart()
256261

257262
return results

0 commit comments

Comments
 (0)