Branch data Line data Source code
1 : : !!****p*ABINIT/anaddb
2 : : !! NAME
3 : : !! anaddb
4 : : !!
5 : : !! FUNCTION
6 : : !! Main routine for analysis of the interatomic force constants and associated properties.
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 1999-2026 ABINIT group (XG,DCA,JCC,CL,XW,GA,MR)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
14 : : !!
15 : : !! INPUTS
16 : : !! (main routine)
17 : : !!
18 : : !! OUTPUT
19 : : !! (main routine)
20 : : !!
21 : : !! SOURCE
22 : :
23 : : #if defined HAVE_CONFIG_H
24 : : #include "config.h"
25 : : #endif
26 : :
27 : : #include "abi_common.h"
28 : :
29 : 162 : program anaddb
30 : :
31 : : use, intrinsic :: iso_c_binding
32 : 162 : use defs_basis
33 : : use m_xmpi
34 : : use m_xomp
35 : : use m_abicore
36 : : use m_errors
37 : : use m_argparse
38 : : use m_nctk
39 : : use netcdf
40 : :
41 : : use m_build_info, only : abinit_version
42 : : use m_io_tools, only : open_file, flush_unit
43 : : use m_fstrings, only : int2char4, itoa, sjoin, strcat, inupper
44 : : use m_specialmsg, only : specialmsg_getcount, herald
45 : : use m_time, only : asctime, timein, timab, cwtime, cwtime_report
46 : : use m_dtfil, only : isfile
47 : : use m_crystal, only : crystal_t
48 : : use m_ddb, only : ddb_type, asrq0_t, ddb_lw_copy
49 : : use m_ddb_hdr, only : ddb_hdr_type
50 : : use m_ifc, only : ifc_type
51 : : use m_anaddb_dataset, only : anaddb_dataset_type
52 : : use m_anaddb_driver, only : anaddb_driver_type
53 : : use m_ddb_interpolate, only : ddb_interpolate
54 : : use m_elphon, only : elphon
55 : : use m_thmeig, only : thmeig
56 : : use m_symfind, only : symanal
57 : : use m_raman, only : ramansus, electrooptic
58 : : use m_ddb_diel, only : ddb_diel
59 : : use m_relaxpol, only : relaxpol
60 : : use m_ddb_elast, only : ddb_elast
61 : : use m_ddb_piezo, only : ddb_piezo
62 : : use m_ddb_internalstr, only : ddb_internalstr
63 : : use m_ddb_flexo, only : ddb_flexo
64 : : use m_ddb_magpen, only : ddb_magpen
65 : : use m_ddb_omega_interpol, only : ddb_omega_interpol
66 : : use m_lwf, only : run_lattice_wannier
67 : : use m_phonons, only : mkphbs
68 : : use m_gruneisen, only : gruns_anaddb
69 : :
70 : : implicit none
71 : :
72 : : !Local variables-------------------------------
73 : : integer, parameter:: master = 0
74 : : integer:: comm, ii, ierr
75 : : integer:: nproc, my_rank, ana_ncid
76 : : logical:: iam_master
77 : : real(dp):: tcpu, tcpui, twall, twalli !,cpu, wall, gflops
78 : : real(dp):: tsec(2)
79 : : integer:: units(2)
80 : : character(len=10):: procstr
81 : : character(len=24):: codename, start_datetime
82 : : ! character(len = strlen):: string, raw_string
83 : : character(len = fnlen):: worker_logfile
84 : : character(len=500):: msg
85 : : type(args_t):: args
86 [ + + ]: 486 : type(anaddb_dataset_type):: dtset
87 : 162 : type(anaddb_driver_type):: driver
88 [ + + + + : 8424 : type(crystal_t):: crystal
+ + + + +
+ + + + +
+ + + + ]
89 [ + + + + ]: 972 : type(ifc_type):: Ifc
90 : 162 : type(ddb_type):: ddb
91 : 162 : type(ddb_type):: ddb_lw
92 [ + + + + : 8424 : type(ddb_hdr_type):: ddb_hdr
+ + + + +
+ + + + +
+ + + + ]
93 : 162 : type(asrq0_t):: asrq0
94 : :
95 : : ! ========================================================================== !
96 : :
97 : : ! Change communicator for I/O (mandatory!)
98 : 162 : call abi_io_redirect(new_io_comm = xmpi_world)
99 : :
100 : : ! These units are defined in defs_basis
101 [ + + ]: 486 : units = [std_out, ab_out]
102 : :
103 : : ! Initialize MPI
104 : 162 : call xmpi_init()
105 : :
106 : : ! MPI variables
107 : 162 : comm = xmpi_world; nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
108 : 162 : iam_master = (my_rank == master)
109 : :
110 : : ! Parse command line arguments.
111 [ - + ]: 162 : args = args_parser(); if (args%exit /= 0) goto 100
112 : :
113 : : ! Initialize memory profiling if activated at configure time.
114 : : ! if a full report is desired, set the argument of abimem_init to "2" instead of "0" via the command line.
115 : : ! note that the file can easily be multiple GB in size so don't use this option normally
116 : : #ifdef HAVE_MEM_PROFILING
117 : : call abimem_init(args%abimem_level, limit_mb = args%abimem_limit_mb)
118 : : #endif
119 : :
120 : : ! Initialisation of the timing
121 : 162 : call timein(tcpui, twalli)
122 : :
123 [ + - ]: 162 : if (iam_master) then
124 : 162 : codename='ANADDB'//repeat(' ',18)
125 : 162 : call herald(codename, abinit_version, std_out)
126 : : end if
127 : :
128 : 162 : start_datetime = asctime()
129 : :
130 : : ! Zero out all accumulators of time and init timers
131 : 162 : call timab(1, 0, tsec)
132 : :
133 : : ! Initialise the code: write heading, and read names of files.
134 [ + - ]: 162 : if (iam_master) then
135 : 162 : call dtset%init(args%input_path)
136 : : end if
137 : :
138 : : ! Broadcast file names
139 : 162 : call dtset%bcast_files(comm)
140 : :
141 : : ! make log file for non-master procs
142 [ - + ]: 162 : if (.not. iam_master) then
143 : 0 : call int2char4(my_rank, procstr)
144 [ # # ]: 0 : ABI_CHECK((procstr(1:1)/='#'), 'Bug: string length too short!')
145 [ # # # # : 0 : worker_logfile = trim(dtset%filename_output) // "_LOG_P" // trim(procstr)
# # ]
146 [ # # ]: 0 : if (open_file(worker_logfile, msg, unit = std_out, form="formatted", action="write") /= 0) then
147 : 0 : ABI_ERROR(msg)
148 : : end if
149 : : end if
150 : :
151 : : ! ========================================================================== !
152 : : ! Read input variables
153 : 162 : call dtset%read_input(comm)
154 : :
155 [ - + ]: 162 : if (args%dry_run /= 0) then
156 : 0 : call wrtout(std_out, "Dry run mode. Exiting after have read the input")
157 : 0 : call dtset%free()
158 : 0 : goto 100
159 : : end if
160 : :
161 : : ! ========================================================================== !
162 : : ! Open output file
163 [ + - ]: 162 : if (iam_master) then
164 : 162 : call isfile(dtset%filename_output, 'new')
165 [ - + ]: 162 : if (open_file(dtset%filename_output, msg, unit=ab_out, form='formatted', status='new') /= 0) then
166 : 0 : ABI_ERROR(msg)
167 : : end if
168 : 162 : rewind (unit = ab_out)
169 : 162 : call herald(codename, abinit_version, ab_out)
170 : :
171 : : ! Echo the inputs to console and main output file
172 : 162 : call dtset%outvars(std_out)
173 : 162 : call dtset%outvars(ab_out)
174 : : else
175 : 0 : ab_out = dev_null
176 : : end if
177 : :
178 : : ! =========================================================================== !
179 : :
180 : : ! Initialize driver
181 : 162 : call driver%init(dtset)
182 : :
183 : : ! Read the DDB information and symmetrize partially the DDB
184 : 162 : write(msg, '(a, a)' )' read the DDB information and perform some checks',ch10
185 : 162 : call wrtout(units, msg)
186 : :
187 : 162 : call ddb%from_file(dtset%filename_ddb, ddb_hdr, crystal, comm, prtvol=dtset%prtvol)
188 : :
189 : : ! Change the bravais lattice if needed
190 : 162 : call ddb%set_brav(dtset%brav)
191 : : ! MR: a new ddb is necessary for the longwave quantities due to incompability of it with automatic reshapes
192 : : ! that ddb%val and ddb%flg experience when passed as arguments of some routines
193 : : ! Copy the long-wave ddb
194 [ + + ]: 162 : if (ddb_hdr%has_d3E_lw) then
195 : 16 : call ddb_lw_copy(ddb, ddb_lw, ddb_hdr)
196 : : end if
197 : :
198 : : ! Acoustic Sum Rule call
199 [ + + ]: 162 : if (dtset%flexoflag == 1 .and. dtset%asr == 6) then
200 : 2 : call driver%get_dcdq(dtset, ddb, ddb_lw, ddb_hdr)
201 : 2 : write(msg, '(a, a)' )' IFCs derivatives read',ch10
202 : 2 : call wrtout(units, msg)
203 : : end if
204 : : ! MR: Second- and third-order total energy derivatives calculated with the
205 : : ! magnetic penalty (constrained DFPT) are converted to physically relevant ones here.
206 [ + + ]: 162 : if (abs(dtset%magpen) > tol8) then
207 : : call ddb_magpen(ddb, ddb_lw, dtset%magpen, dtset%mpatpol, &
208 : : & dtset%mpdir, dtset%mpert, dtset%mpopt, Crystal%natom, dtset%prtvol, 1, Crystal%ucvol, dtset%timdisp, &
209 : 6 : & Crystal%xred)
210 : :
211 [ + - ]: 6 : if (dtset%freqflag/=0) then
212 : : call ddb_omega_interpol(Crystal%amu, ddb, ddb_lw, dtset%eta, dtset%prefix_outdata, &
213 : : & dtset%magpen, dtset%mpatpol, dtset%mpdir, dtset%mpert, dtset%mpopt, Crystal%natom, dtset%nfreq, Crystal%ntypat, &
214 : 6 : & dtset%freqflag, dtset%frmax, dtset%frmin, dtset%prtvol, Crystal%typat, Crystal%ucvol, Crystal%xred)
215 : : end if
216 : :
217 : : !Proceed with a normal anaddb run with relaxed- or fixed-spin quantities
218 [ - + ]: 6 : if (dtset%mpopt==1) then
219 [ # # # # : 0 : ddb%val= ddb%val_fs
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
220 [ + - ]: 6 : else if (dtset%mpopt==2) then
221 [ + - + - : 114284 : ddb%val= ddb%val_rs
+ - + - -
- - - - -
- - - - -
- - - + +
+ + + + ]
222 : : end if
223 : : end if
224 : :
225 : :
226 : : ! ! TODO: This is to maintain the previous behaviour in which all the arrays were initialized to zero.
227 : : ! ! In the new version asrq0%d2asr is always computed if the Gamma block is present
228 : : ! ! and this causes changes in [v5][t28]
229 : : ! if (.not. (dtset%ifcflag == 0 .or. dtset%instrflag /= 0 .or. dtset%elaflag /= 0)) then
230 : : ! asrq0%d2asr = zero
231 : : ! if (asrq0%asr == 3 .or. asrq0%asr == 4) then
232 : : ! asrq0%singular = zero; asrq0%uinvers = zero; asrq0%vtinvers = zero
233 : : ! end if
234 : : ! end if
235 : :
236 : : ! Acoustic Sum Rule
237 : : ! In case the interatomic forces are not calculated, the
238 : : ! ASR-correction (asrq0%d2asr) has to be determined here from the Dynamical matrix at Gamma.
239 : 162 : call asrq0%init(ddb, dtset%asr, dtset%rfmeth, crystal, dtset%sys_dim, driver%dcdq, driver%dcdqdq)
240 : :
241 : : ! Open netcdf output and write basic quantities
242 : 162 : call driver%open_write_nc(ana_ncid, dtset, crystal, comm)
243 : :
244 : : ! =========================================================================== !
245 : :
246 : : ! Compute dielectric tensor, Born effective charges, and quadrupoles.
247 [ + + ]: 162 : if (driver%do_electric_tensors) then
248 : 152 : call driver%electric_tensors(dtset, crystal, ddb, ddb_lw, ddb_hdr, ana_ncid, comm)
249 : : end if
250 : :
251 : : ! If low-dimensional systems, convert dielectric tensors if present
252 [ + + ]: 162 : if (dtset%sys_dim>1 .and. dtset%dipdip>0) then
253 : 4 : call driver%convertdim_dielt(crystal%rprimd, dtset%sys_dim,dtset%dielt_thick)
254 : : end if
255 : :
256 : : ! Structural response at fixed polarization
257 [ + + ]: 162 : if (dtset%polflag == 1) then
258 : 6 : call driver%structural_response(dtset, crystal, ddb)
259 : : end if
260 : :
261 : : ! Compute non-linear optical susceptibilities
262 : : ! and first-order change in the linear dielectric susceptibility
263 [ + + ]: 162 : if (dtset%nlflag > 0) then
264 : 8 : call driver%susceptibilities(dtset, ddb, ana_ncid, comm)
265 : : end if
266 : :
267 : : ! Interatomic force constants
268 [ + + ]: 162 : if (driver%do_ifc) then
269 : 108 : call driver%interatomic_force_constants(Ifc, dtset, crystal, ddb, ana_ncid, comm)
270 [ - + ]: 108 : if (dtset%flexoflag /= 1 .and. dtset%asr == 6) then
271 : 0 : write(msg, '(a, a)' )' IFCs derivatives computed from real-space moment',ch10
272 : 0 : call wrtout(units, msg)
273 : 0 : call asrq0%init(ddb, dtset%asr, dtset%rfmeth, crystal, dtset%sys_dim, driver%dcdq, driver%dcdqdq)
274 : : end if
275 : : end if
276 : :
277 : : ! Phonon density of states
278 [ + + ]: 162 : if (driver%do_phonon_dos) then
279 : 22 : call driver%phdos(dtset, crystal, Ifc, comm)
280 : : end if
281 : :
282 : : ! Phonon density of states and thermodynamical properties calculation
283 [ + + + + : 470 : if (dtset%ifcflag == 1 .and. any(dtset%thmflag==[1, 2])) then
+ + ]
284 : 8 : call driver%harmonic_thermo(dtset, crystal, Ifc, comm)
285 : : end if
286 : :
287 : : ! Phonon band structure
288 [ + + ]: 162 : if (driver%do_phonon_bs) then
289 : 130 : call mkphbs(Ifc, crystal, dtset, ddb, asrq0, dtset%prefix_outdata, comm)
290 : : end if
291 : :
292 : : ! DDB interpolation
293 [ + + ]: 162 : if (dtset%prtddb == 1 .and. dtset%ifcflag == 1) then
294 : 2 : call ddb_interpolate(Ifc, crystal, dtset, ddb, ddb_hdr, asrq0, comm)
295 : : end if
296 : :
297 : : ! =========================================================================== !
298 : : ! Electron-phonon section
299 : :
300 [ + + ]: 162 : if (dtset%elphflag == 1) then
301 : 30 : call elphon(dtset, crystal, Ifc, comm)
302 : : end if
303 : :
304 : : ! Thermal supercell calculation
305 [ + + + + : 2106 : if (sum(abs(dtset%thermal_supercell))>0 .and. dtset%ifcflag == 1) then
+ + ]
306 : 2 : call driver%thermal_supercell(dtset, crystal, ifc)
307 : : end if
308 : :
309 : : ! Thermal corrections to eigenvalues (old)
310 [ + + ]: 162 : if (dtset%thmflag >= 3 .and. dtset%thmflag <= 8) then
311 : 14 : call thmeig(dtset, ddb, crystal, ab_out, crystal%natom, dtset%mpert, dtset%msize, asrq0%d2asr, comm)
312 : : end if
313 : :
314 : : ! =========================================================================== !
315 : :
316 : : ! Compute the dielectric function and oscillator strength.
317 [ + + ]: 162 : if (driver%do_dielectric_q0) then
318 : 54 : call driver%dielectric_q0(dtset, crystal, ifc, ddb, asrq0, ana_ncid, comm)
319 : : end if
320 : :
321 : : ! Non-linear response: electrooptic and Raman (q = Gamma, TO modes only)
322 [ + + ]: 162 : if (dtset%nlflag == 1) then
323 : 4 : call driver%nonlinear_response(dtset, crystal, ana_ncid, comm)
324 : : end if
325 : :
326 : : ! Non-analyticity in the dynamical matrix
327 [ + + ]: 162 : if (driver%do_dielectric_nonana) then
328 : 48 : call driver%dielectric_nonana(dtset, crystal, ddb, ana_ncid, comm)
329 : : end if
330 : :
331 : : ! =========================================================================== !
332 : : ! Linear response with strain
333 : :
334 : : ! Internal strain (needed for the other linear response functions)
335 [ + + ]: 162 : if (dtset%instrflag /= 0) then
336 : 12 : call driver%internal_strain(dtset, ddb, asrq0)
337 : : end if
338 : :
339 : : ! Elastic tensor
340 [ + + ]: 162 : if (dtset%elaflag /= 0) then
341 : 12 : call driver%elastic_tensor(dtset, crystal, ddb, asrq0, ana_ncid)
342 : : end if
343 : :
344 : : ! Piezoelectric tensor
345 [ + + ]: 162 : if (dtset%piezoflag /= 0 .or. dtset%dieflag == 4 .or. dtset%elaflag == 4) then
346 : 10 : call driver%piezoelectric_tensor(dtset, crystal, ddb, ana_ncid)
347 : : end if
348 : :
349 : : ! Flexoelectric tensor
350 [ + + ]: 162 : if (dtset%flexoflag /= 0) then
351 : 4 : call driver%flexoelectric_tensor(dtset, crystal, ddb, ddb_lw, ddb_hdr, asrq0)
352 : : end if
353 : :
354 : : ! =========================================================================== !
355 : :
356 : : ! Gruneisen parameters
357 [ + + ]: 162 : if (dtset%gruns_nddbs /= 0) then
358 : 2 : call gruns_anaddb(dtset, comm)
359 : : end if
360 : :
361 : : ! Lattice Wannier functions
362 [ + + ]: 162 : if (dtset%ifcflag == 1 .and. dtset%lwfflag > 0 ) then
363 : 6 : call driver%lattice_wannier(dtset, crystal, Ifc, comm)
364 : : endif
365 : :
366 : : ! Output phonon frequencies for BoltzTrap
367 [ + + ]: 162 : if (iam_master .and. dtset%ifcflag == 1 .and. dtset%outboltztrap == 1) then
368 : 2 : call ifc%outphbtrap(crystal, dtset%ng2qpt, 1, dtset%q2shft, dtset%prefix_outdata)
369 : : end if
370 : :
371 : : ! =========================================================================== !
372 : : ! Close netcdf file
373 [ + - ]: 162 : if (iam_master) then
374 [ - + ]: 162 : NCF_CHECK(nf90_close(ana_ncid))
375 : : end if
376 : :
377 : : ! =========================================================================== !
378 : : ! Free memory
379 : 162 : call asrq0%free()
380 : 162 : call ifc%free()
381 : 162 : call crystal%free()
382 : 162 : call ddb%free()
383 : 162 : call ddb_hdr%free()
384 : 162 : call ddb_lw%free()
385 : 162 : call driver%free()
386 : 162 : call dtset%free()
387 : :
388 : : ! =========================================================================== !
389 : : ! Output timing and memory reports, then close output files
390 : :
391 : 162 : call timein(tcpu, twall)
392 : 162 : tsec(1)=tcpu-tcpui; tsec(2)=twall-twalli
393 : 162 : write(msg, '(a, i4, a, f13.1, a, f13.1)' )' Proc.',my_rank, ' individual time (sec): cpu=',tsec(1), ' wall=',tsec(2)
394 : 162 : call wrtout(std_out, msg)
395 : :
396 [ + - ]: 162 : if (iam_master) then
397 : 162 : write(ab_out, '(a, a, a, i4, a, f13.1, a, f13.1)' )'-',ch10, &
398 : 324 : '- Proc.',my_rank, ' individual time (sec): cpu=',tsec(1), ' wall=',tsec(2)
399 : : end if
400 : :
401 : 162 : call xmpi_sum(tsec, comm, ierr)
402 : :
403 : 162 : write(msg, '(a, (80a), a, a, a, f11.3, a, f11.3, a, a, a, a)' ) ch10, &
404 [ + + ]: 13284 : ('=',ii = 1, 80), ch10, ch10, &
405 : 162 : '+Total cpu time',tsec(1), ' and wall time',tsec(2), ' sec',ch10, ch10, &
406 [ - + ]: 13446 : ' anaddb : the run completed successfully.'
407 : 162 : call wrtout(units, msg)
408 : :
409 [ + - ]: 162 : if (iam_master) then
410 : : ! Write YAML document with the final summary.
411 : : ! we use this doc to test whether the calculation is completed.
412 : 162 : write(std_out, "(a)")"--- !FinalSummary"
413 : 162 : write(std_out, "(a)")"program: anaddb"
414 : 162 : write(std_out, "(2a)")"version: ",trim(abinit_version)
415 : 162 : write(std_out, "(2a)")"start_datetime: ",start_datetime
416 : 162 : write(std_out, "(2a)")"end_datetime: ",asctime()
417 : 162 : write(std_out, "(a, f13.1)")"overall_cpu_time: ",tsec(1)
418 : 162 : write(std_out, "(a, f13.1)")"overall_wall_time: ",tsec(2)
419 : 162 : write(std_out, "(a, i0)")"mpi_procs: ",xmpi_comm_size(xmpi_world)
420 : 162 : write(std_out, "(a, i0)")"omp_threads: ",xomp_get_num_threads(open_parallel=.True.)
421 : : !write(std_out, "(a, i0)")"num_warnings: ",nwarning
422 : : !write(std_out, "(a, i0)")"num_comments: ",ncomment
423 : 162 : write(std_out, "(a)")"..."
424 : 162 : call flush_unit(std_out)
425 : : end if
426 : :
427 : : ! Write information on file about the memory before ending mpi module, if memory profiling is enabled
428 : 162 : call abinit_doctor(dtset%filename_output)
429 : :
430 : 162 : call flush_unit(ab_out)
431 : 162 : call flush_unit(std_out)
432 : :
433 [ + - ]: 162 : if (iam_master) close(ab_out)
434 : :
435 : 162 : 100 call xmpi_end()
436 : :
437 : 0 : end program anaddb
438 : : !!***
439 : :
|