Branch data Line data Source code
1 : : !!****m* ABINIT/m_mlwfovlp
2 : : !! NAME
3 : : !! m_mlwfovlp
4 : : !!
5 : : !! FUNCTION
6 : : !! Interface with Wannier90
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2005-2026 ABINIT group (BAmadon, CEspejo, FJollet, TRangel, DRH, hexu, MG)
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 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : module m_mlwfovlp
23 : :
24 : : use, intrinsic :: iso_c_binding
25 : : use defs_basis
26 : : use defs_wannier90
27 : : use m_abicore
28 : : use m_errors
29 : : use m_atomdata
30 : : use m_xmpi
31 : : use m_sort
32 : : #ifdef FC_NAG
33 : : use f90_unix_dir
34 : : #endif
35 : : use netcdf
36 : : use m_nctk
37 : : use m_hdr
38 : : use m_dtset
39 : : use m_dtfil
40 : : use m_krank
41 : : use m_yaml
42 : :
43 : : use defs_datatypes, only : pseudopotential_type
44 : : use defs_abitypes, only : MPI_type
45 : : use m_time, only : cwtime, cwtime_report
46 : : use m_io_tools, only : delete_file, get_unit, open_file
47 : : use m_hide_lapack, only : matrginv, xheev
48 : : use m_fstrings, only : strcat, sjoin, itoa
49 : : use m_numeric_tools, only : uniformrandom, simpson_int, c2r, l2int, isdiagmat, get_diag, blocked_loop
50 : : use m_special_funcs, only : besjm
51 : : use m_geometry, only : xred2xcart, rotmat, wigner_seitz
52 : : use m_crystal, only : crystal_t
53 : : use m_fftcore, only : sphereboundary
54 : : use m_ebands, only : ebands_t
55 : : use m_pawang, only : pawang_type
56 : : use m_pawrad, only : pawrad_type, simp_gen
57 : : use m_pawtab, only : pawtab_type
58 : : use m_pawcprj, only : pawcprj_type
59 : : use m_paw_sphharm, only : ylm_cmplx, initylmr
60 : : use m_paw_overlap, only : smatrix_pawinit
61 : : use m_evdw_wannier, only : evdw_wannier
62 : : use m_abstract_wf, only: abstract_wf, wann_ksetting_t, cg_cprj, wfd_wf
63 : : use m_wannier_io, only: write_eigenvalues, write_Amn, compute_and_write_unk, write_Mmn
64 : :
65 : : implicit none
66 : :
67 : : private
68 : : !!***
69 : :
70 : : public :: mlwfovlp
71 : : !!***
72 : :
73 : : !----------------------------------------------------------------------
74 : :
75 : : !!****t* m_mlwfovlp/wan_t
76 : : !! NAME
77 : : !! wan_t
78 : : !!
79 : : !! FUNCTION
80 : : !! This object stores the results of the Wannnierization algorithm.
81 : : !! It can be constructed by reading the ABIWAN.nc file produced by
82 : : !! Abinit when we call wannier90 in library mode. See mlwfovlp routine.
83 : : !!
84 : : !! SOURCE
85 : :
86 : : type,public :: wan_t
87 : :
88 : : integer :: spin = -1
89 : : ! Spin index.
90 : :
91 : : integer :: nwan = -1
92 : : ! Number of Wannier functions.
93 : :
94 : : integer :: max_nwan = -1
95 : : ! Max number of Wannier functions over spins (used to dimension arrays)
96 : :
97 : : integer :: num_bands = -1
98 : : ! Number of bands seen by wannier90 for this spin.
99 : :
100 : : !integer :: nbndep, ! Number of remaining bands after excluding bands in Wannierizatin step
101 : : !integer :: nbndskip, ! Number of bands to be skipped in Wannierization step, leading to
102 : : ! the exclusion from the original Hamiltonian
103 : : integer :: nkbz = -1
104 : : ! Number of k-points in the full BZ.
105 : :
106 : : integer :: nr_h = -1, nr_e = -1, nr_p = -1
107 : : ! Number of lattice points for H, electrons, phonons.
108 : :
109 : : integer :: ngkpt(3) = -1
110 : : ! K-mesh divisions.
111 : :
112 : : !integer :: nshiftk
113 : : ! Number of shifts. At present only 1 shift is supported.
114 : :
115 : : logical :: have_disentangled
116 : : ! True if disentanglement has been used.
117 : :
118 : : real(dp) :: spread(3) = -one
119 : : ! Spread of wannier functions.
120 : :
121 : : type(krank_t) :: krank
122 : : ! Used to find the index of the kpoint from its coordinates.
123 : :
124 : : integer,allocatable :: exclude_bands(:)
125 : : ! FIXME: Is this still needed?
126 : :
127 : : integer,allocatable :: dimwin(:), winstart(:)
128 : : ! (nkbz)
129 : : ! Number of bands within the outer window at each k-point
130 : :
131 : : integer :: bmin = -1, bmax = -1
132 : : ! Minimum and maximum band included in the Wannierization.
133 : :
134 : : integer,allocatable :: r_h(:,:), r_e(:,:), r_p(:,:)
135 : : ! Lattice points for H in the Wannier representation
136 : : ! (3, nr_h)
137 : :
138 : : integer,allocatable :: ndegen_h(:), ndegen_e(:), ndegen_p(:)
139 : :
140 : : real(dp),allocatable :: rmod_h(:), rmod_p(:), rmod_e(:)
141 : : ! (nr_h), (nr_p)
142 : : ! Lenght of the lattice points in Bohr
143 : :
144 : : real(dp),allocatable :: all_eigens(:,:)
145 : : ! (mband, nkbz)
146 : : ! All KS eigenvalues (before possible filtering done by wannier90)
147 : :
148 : : real(dp),allocatable :: centres(:,:)
149 : : ! Wannier centers.
150 : : ! (3, nwan)
151 : :
152 : : real(dp),allocatable :: spreads(:)
153 : : ! Wannier centers.
154 : : ! (nwan)
155 : :
156 : : real(dp),allocatable :: kbz(:,:)
157 : : ! kpoints in the full BZ used by Wannier90.
158 : : ! (3, nkbz)
159 : :
160 : : logical,allocatable :: band_in(:)
161 : : ! (num_bands)
162 : :
163 : : logical,allocatable :: lwindow(:,:)
164 : : ! (num_bands, nkbz)
165 : :
166 : : logical :: keep_umats
167 : : ! True of u_mat_opt and u_mat should be saved in memory.
168 : :
169 : : complex(dp),allocatable :: u_mat_opt(:,:,:)
170 : : complex(dp),allocatable :: u_mat(:,:,:)
171 : :
172 : : complex(dp),allocatable :: u_k(:,:,:)
173 : : ! (max_dimwin, nwan, nkbz)
174 : : ! total rotation matrix: the product of the optimal subspace x the rotation among the nwan Wannier functions.
175 : : ! on the coarse ab-initio k-mesh
176 : :
177 : : complex(dp),allocatable :: hwan_r(:,:,:)
178 : : ! (nr_h, nwan, nwan)
179 : : ! KS Hamiltonian in the Wannier representation.
180 : :
181 : : integer :: my_npert = -1, my_pert_start = -1
182 : : ! My number of perturbations and my initial perturbation.
183 : :
184 : : type(xcomm_t), pointer :: pert_comm => null()
185 : : ! MPI-communicator for parallelism over perturbations.
186 : :
187 : : complex(dp),allocatable :: grpe_wwp(:,:,:,:,:)
188 : : ! (nr_p, nr_e, nwan, nwan, my_npert))
189 : : ! e-ph matrix elements in the Wannier representation.
190 : : ! NB: These matrix elements are in the atomic represention and distributed inside pert_comm.
191 : :
192 : : contains
193 : : procedure :: from_abiwan => wan_from_abiwan
194 : : ! Initialize a wan_t instance from a ABIWAN.nc file
195 : :
196 : : procedure :: load_gwan => wan_load_gwan
197 : : ! Read g(R_p, R_e) in the Wannier representation from the GWAN.nc file.
198 : :
199 : : procedure :: print => wan_print
200 : : ! Print info on the object.
201 : :
202 : : procedure :: interp_ham => wan_interp_ham
203 : : ! Interpolate Hamiltonian at an arbitray k-point.
204 : : ! energies, and optionally diagonal velocities.
205 : :
206 : : procedure :: setup_eph_ws_kq => wan_setup_eph_ws_kq
207 : : ! Prepare interpolation of e-ph matrix elements.
208 : :
209 : : procedure :: interp_eph_manyq => wan_interp_eph_manyq
210 : : ! Interpolate e-ph matrix elements.
211 : :
212 : : procedure :: interp_eph_manyk => wan_interp_eph_manyk
213 : : ! Interpolate e-ph matrix elements for many k points at fixed q.
214 : :
215 : : procedure :: prepare_eph_q => wan_prepare_eph_q
216 : : ! Fourier transform the e-ph vertex from R_p to one q point.
217 : :
218 : : procedure :: interp_eph_manyk_from_q => wan_interp_eph_manyk_from_q
219 : : ! Interpolate a k batch from a q-prepared e-ph vertex.
220 : :
221 : : procedure :: eph_kbatch_size => wan_eph_kbatch_size
222 : : ! Select a k-batch size from a configurable workspace limit.
223 : :
224 : : procedure :: ncwrite_gwan => wan_ncwrite_gwan
225 : : ! Write g in the Wannier representation to netcdf file.
226 : :
227 : : procedure :: free => wan_free
228 : : ! Free memory.
229 : :
230 : : end type wan_t
231 : : !!***
232 : :
233 : : public :: wan_interp_ebands
234 : : ! Build new ebands_t object on a k-mesh via Wannier interpolation.
235 : :
236 : : contains
237 : : !!***
238 : :
239 : : !!****f* m_mlwfovlp/mlwfovlp
240 : : !! NAME
241 : : !! mlwfovlp
242 : : !!
243 : : !! FUNCTION
244 : : !! Routine which computes overlap M_{mn}(k,b) and projection A_{mn}(k)
245 : : !! for Wannier code (www.wannier.org f90 version).
246 : : !! Various file are written (wannier90.*) which can be used to run a
247 : : !! separate wannier calculation with the wannier90 code.
248 : : !!
249 : : !! INPUTS
250 : : !! crystal<crystal_t>=Info on the crystalline structure.
251 : : !! ebands<ebands_t>=The object describing the band structure.
252 : : !! hdr <type(hdr_type)>=the header of wf, den and pot files
253 : : !! atindx1(natom)=index table for atoms, inverse of atindx (see gstate.f)
254 : : !! cg(2,mcg)=planewave coefficients of wavefunctions.
255 : : !! cprj(natom,mcprj)= <p_lmn|Cnk> coefficients for each WF |Cnk> and each |p_lmn> non-local projector
256 : : !! dtset <type(dataset_type)>=all input variables for this dataset
257 : : !! dtfil <type(datafiles_type)>=variables related to files
258 : : !! ecut=cut-off energy for plane wave basis sphere (Ha)
259 : : !! eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
260 : : !! gprimd(3,3)=dimensional reciprocal space primitive translations
261 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates.
262 : : !! mband=maximum number of bands
263 : : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
264 : : !! mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
265 : : !! mgfft=maximum size of 1D FFTs
266 : : !! mgfftc=maximum size of 1D FFTs (coarse grid)
267 : : !! mkmem =number of k points treated by this node.
268 : : !! mpi_enreg=information about MPI parallelization
269 : : !! mpw=maximum dimensioned size of npw.
270 : : !! natom=number of atoms in cell.
271 : : !! nattyp(ntypat)= # atoms of each type.
272 : : !! nfft=(effective) number of FFT grid points (for this processor) (see NOTES at beginning of scfcv)
273 : : !! ngfft(18)=contain all needed information about 3D FFT (see NOTES at beginning of scfcv)
274 : : !! nkpt=number of k points.
275 : : !! npwarr(nkpt)=number of planewaves in basis at this k point
276 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
277 : : !! ntypat=number of types of atoms in unit cell.
278 : : !! occ(mband*nkpt*nsppol) Occupation number for each band (often 2) for each k point.
279 : : !! prtvol=control print volume and debugging output
280 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
281 : : !! rprimd(3,3)=dimensional primitive translations for real space (bohr)
282 : : !! ucvol=unit cell volume (bohr**3)
283 : : !! xred(3,natom)=reduced dimensionless atomic coordinates
284 : : !!
285 : : !! OUTPUT
286 : : !! (only writing, printing)
287 : : !!
288 : : !! SIDE EFFECTS
289 : : !! (only writing, printing)
290 : : !!
291 : : !! NOTES
292 : : !!
293 : : !! SOURCE
294 : :
295 : 19 : subroutine mlwfovlp(mywfc, crystal, ebands, hdr, atindx1, &
296 : : !&cg,cprj, &
297 : 19 : dtset,dtfil,eigen,gprimd,kg,&
298 : : mband,mcg,mcprj,mgfftc,mkmem,mpi_enreg,mpw,natom,&
299 : 38 : nattyp,nfft,ngfft,nkpt,npwarr,nsppol,ntypat,occ,&
300 [ - + - + : 19 : pawang,pawrad,pawtab,prtvol,psps,rprimd,ucvol,xred, exclude_bands)
- + ]
301 : :
302 : : !Arguments ------------------------------------
303 : : !scalars
304 : : class(abstract_wf), pointer :: mywfc
305 : : integer,intent(in) :: mband,mcg,mcprj,mgfftc,mkmem,mpw,natom,nfft,nkpt
306 : : integer,intent(in) :: nsppol,ntypat,prtvol
307 : : real(dp),intent(in) :: ucvol
308 : : type(crystal_t),intent(in) :: crystal
309 : : type(ebands_t),intent(in) :: ebands
310 : : type(hdr_type),intent(in) :: hdr
311 : : type(MPI_type),intent(inout) :: mpi_enreg
312 : : type(dataset_type),intent(in) :: dtset
313 : : type(datafiles_type),intent(in) :: dtfil
314 : : type(pawang_type),intent(in) :: pawang
315 : : type(pseudopotential_type),intent(in) :: psps
316 : : !arrays
317 : : integer,intent(in) :: atindx1(natom)
318 : : integer,intent(in) :: kg(3,mpw*mkmem),nattyp(ntypat),ngfft(18),npwarr(nkpt)
319 : : ! real(dp), optional, intent(in) :: cg(2,mcg)
320 : : ! type(pawcprj_type), optional, intent(in) :: cprj(natom,mcprj)
321 : : real(dp),optional, intent(in) :: eigen(mband*nkpt*nsppol),gprimd(3,3),rprimd(3,3)
322 : : real(dp),intent(in) :: occ(mband*nkpt*nsppol)
323 : : real(dp),intent(in) :: xred(3,natom)
324 : : !type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
325 : : !type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
326 : : type(pawrad_type),intent(in) :: pawrad(:)
327 : : type(pawtab_type),intent(in) :: pawtab(:)
328 : : integer, intent(inout) :: exclude_bands(:,:)
329 : :
330 : : !Local variables-------------------------------
331 : : !scalars
332 : : integer :: i, ierr, ikpt1,ikpt2,intot,isppol, iwan, lproj,lwanniersetup,mwan
333 : : #if defined HAVE_WANNIER90
334 : : integer :: ncid, ncerr, nrpts
335 : : character(len=fnlen) :: abiwan_fname
336 : 38 : integer :: have_disentangled_spin(nsppol)
337 : 19 : integer,allocatable :: irvec_r_h(:,:),ndegen_h(:)
338 : 19 : real(dp),allocatable :: rmods_r_h(:)
339 : : !type(wan_t) :: wan
340 : : #endif
341 : : integer,parameter :: master = 0
342 : : integer :: nntot,num_nnmax
343 : : integer :: max_num_bands,nprocs,comm,rank
344 : 57 : integer :: nwan(nsppol),nband_inc(nsppol),num_bands(nsppol)
345 : : logical :: gamma_only,leig,lmmn,lwannierrun,spinors,test_matrix_output !,have_disentangled
346 : : character(len=fnlen) :: wfnname
347 : : character(len=1000) :: msg
348 : 38 : character(len=fnlen) :: seed_name(nsppol)
349 : 38 : character(len=fnlen) :: filew90_win(nsppol),filew90_wout(nsppol),filew90_amn(nsppol),filew90_ramn(nsppol)
350 : 38 : character(len=fnlen) :: filew90_mmn(nsppol),filew90_eig(nsppol)
351 : : !arrays
352 : : integer :: g1temp(3),ngkpt(3), units(2)
353 : 19 : integer,allocatable :: g1(:,:,:)
354 : 19 : integer,allocatable:: ovikp(:,:)
355 : 19 : integer,allocatable :: proj_l(:,:),proj_m(:,:),proj_radial(:,:)
356 : 19 : integer,allocatable :: proj_s_loc(:)
357 : : real(dp) :: real_lattice(3,3), recip_lattice(3,3)
358 : 19 : real(dp),allocatable :: cm1(:,:,:,:,:,:),cm2_paw(:,:,:)
359 : 19 : real(dp),allocatable :: eigenvalues_w(:,:,:)
360 : 19 : real(dp),allocatable :: proj_site(:,:,:),proj_x(:,:,:),proj_z(:,:,:),proj_zona(:,:)
361 : 19 : real(dp),allocatable :: wann_centres(:,:,:),wann_spreads(:,:),xcart(:,:)
362 : 19 : real(dp),allocatable :: proj_s_qaxis_loc(:,:)
363 : 19 : complex(dp),allocatable :: A_paw(:,:,:,:)
364 : 19 : complex(dp),allocatable :: M_matrix(:,:,:,:,:),U_matrix(:,:,:,:)
365 : 19 : complex(dp),allocatable :: U_matrix_opt(:,:,:,:)
366 : 19 : complex(dp),pointer :: A_matrix(:,:,:,:)
367 : 19 : logical,allocatable :: band_in(:,:),lwindow(:,:,:)
368 : 19 : character(len=3),allocatable :: atom_symbols(:)
369 : 19 : logical,allocatable:: just_augmentation(:,:)
370 : 19 : type(pawcprj_type), pointer :: cprj_ptr(:, :)
371 : : #ifdef HAVE_WANNIER90
372 : 38 : real(dp) :: spreadw(3,nsppol)
373 : : #endif
374 : : !************************************************************************
375 : :
376 : : ABI_UNUSED((/crystal%natom, ebands%nkpt, hdr%nkpt/))
377 : : ABI_UNUSED(atindx1)
378 : : ABI_UNUSED((/mcg, mcprj, prtvol/))
379 : 19 : ABI_UNUSED_A(pawang)
380 : :
381 [ + + ]: 57 : units = [std_out, ab_out]
382 : :
383 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
384 : : !1) Initialize variables and allocations
385 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
386 : : !
387 : : !Some initialization and checks
388 : : !
389 : 19 : lwanniersetup=1 ! 1 is mandatory ( 0 is for debug)
390 : : !to use lwanniersetup=0, one would need to define which bands to exclude.
391 : 19 : lwannierrun=.true. ! .false. and .true. are possible
392 : 19 : lmmn=.true. ! .false. and .true. are possible
393 : 19 : leig=.true. ! .false. and .true. are possible
394 : 19 : gamma_only=.false. !not yet implemented
395 : 19 : spinors=.false.
396 [ + + ]: 19 : if (dtset%nspinor == 2) spinors = .true.
397 : : ! Raw A_mn and M_mn entries are suitable regression quantities only for
398 : : ! scalar wavefunctions. Spinor eigenvectors have additional gauge freedom.
399 : 19 : test_matrix_output = dtset%nspinor == 1
400 : :
401 : : !mpi initialization
402 : 19 : comm=MPI_enreg%comm_cell
403 : 19 : nprocs=xmpi_comm_size(comm)
404 : 19 : rank=MPI_enreg%me_kpt
405 : : !write(std_out,'("master ",i0," rank ",i0," nprocs ",i0)') master,rank,nprocs
406 : :
407 : : !Generate seed names for wannier90 files, and file names
408 : : call mlwfovlp_seedname(dtfil%fnameabo_w90,filew90_win,filew90_wout,filew90_amn,&
409 : 19 : filew90_ramn,filew90_mmn,filew90_eig,nsppol,seed_name)
410 : :
411 : 19 : call hdr%vs_dtset(dtset)
412 : :
413 : : ! Check that the WFK contains the full Brillouin-zone mesh required by Wannier90.
414 : : ! Use the arrays stored in the WFK header: dtset%istwfk and dtset%wtk may only
415 : : ! contain the compact input representation and therefore need not have nkpt entries.
416 [ + - ]: 19 : if (rank == master) then
417 [ + + + - : 1299 : if (.not. (all(hdr%istwfk(1:nkpt) == 1) .and. all(hdr%wtk(1:nkpt) == hdr%wtk(1)))) then
+ + + - -
+ ]
418 : 0 : write(msg, '(4a)') ch10, &
419 : 0 : ' mlwfovlp: you should provide k-points in the full Brillouin zone ', ch10, &
420 : 0 : ' with explicit k-points (or kptopt=3) and istwfk 1'
421 : 0 : call wrtout(units, msg)
422 : 0 : ABI_ERROR(msg)
423 : : end if
424 : : end if
425 : :
426 [ - + ]: 19 : if(MPI_enreg%paral_spinor==1) then
427 : 0 : ABI_ERROR('Parallelization over spinorial components not yet available !')
428 : : end if
429 : :
430 : : ! MG: TODO: Why this check?
431 [ - + ]: 19 : if (psps%npsp/=psps%ntypat) then
432 : 0 : ABI_ERROR("Alchemical mixing not supported in mlwfovlp")
433 : : end if
434 : :
435 [ + + ]: 19 : if (nsppol==2) then
436 : 1 : write(msg, '(3a)' ) ch10,' mlwfovlp: Calculating matrices for both spin polarization ',ch10
437 : 1 : call wrtout(units, msg)
438 : : end if
439 : :
440 : : ! get lattice parameters in wannier90 format
441 [ + + ]: 76 : do i=1, 3
442 [ + + ]: 228 : real_lattice(:,i)=Bohr_Ang*rprimd(i,:)
443 [ + + ]: 247 : recip_lattice(:,i)=two_pi*gprimd(i,:)/Bohr_Ang
444 : : end do
445 : :
446 : : ! Allocations.
447 : 19 : num_nnmax=12 ! limit fixed for compact structure in wannier_setup.
448 [ - + + - : 76 : ABI_MALLOC(g1,(3,nkpt,num_nnmax))
+ - + - +
- - + - +
- + ]
449 [ - + + - : 76 : ABI_MALLOC(ovikp,(nkpt,num_nnmax))
+ - + - +
- - + - +
- + ]
450 [ - + + - : 57 : ABI_MALLOC(atom_symbols,(natom))
+ - + - -
+ - + ]
451 [ - + + - : 57 : ABI_MALLOC(xcart,(3,natom))
+ - + - -
+ - + -
+ ]
452 [ - + + - : 76 : ABI_MALLOC(band_in,(mband,nsppol))
- + + - +
- + - - +
- + - + ]
453 [ - + + - : 76 : ABI_MALLOC(proj_site,(3,mband,nsppol))
- + + - +
- + - - +
- + ]
454 [ - + + - : 57 : ABI_MALLOC(proj_l,(mband,nsppol))
- + + - -
+ - + ]
455 [ - + + - : 57 : ABI_MALLOC(proj_m,(mband,nsppol))
- + + - -
+ - + ]
456 [ - + + - : 57 : ABI_MALLOC(proj_radial,(mband,nsppol))
- + + - -
+ - + ]
457 [ - + + - : 57 : ABI_MALLOC(proj_x,(3,mband,nsppol))
- + + - -
+ - + ]
458 [ - + + - : 57 : ABI_MALLOC(proj_s_loc,(mband))
+ - + - -
+ - + ]
459 [ - + + - : 57 : ABI_MALLOC(proj_s_qaxis_loc,(3,mband))
+ - + - -
+ - + ]
460 [ - + + - : 57 : ABI_MALLOC(proj_z,(3,mband,nsppol))
- + + - -
+ - + ]
461 [ - + + - : 76 : ABI_MALLOC(proj_zona,(mband,nsppol))
- + + - +
- + - - +
- + ]
462 : : ! ABI_MALLOC(exclude_bands, (mband,nsppol))
463 : : !
464 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
465 : : !2) Call to Wannier setup
466 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
467 : : !
468 : 19 : nullify(A_matrix)
469 : :
470 : : call mlwfovlp_setup(atom_symbols,band_in,dtset,filew90_win,gamma_only,&
471 : : g1,lwanniersetup,mband,natom,nband_inc,nkpt,&
472 : : nntot,num_bands,num_nnmax,nsppol,nwan,ovikp,&
473 : : proj_l,proj_m,proj_radial,proj_site,proj_s_loc, proj_s_qaxis_loc, proj_x,proj_z,proj_zona,&
474 [ - + - - : 19 : real_lattice,recip_lattice,rprimd,seed_name,spinors,xcart,xred,exclude_bands)
- + - - -
- ]
475 : :
476 [ + + ]: 39 : do isppol=1, nsppol
477 : 20 : write(msg, '(6a)' ) ch10,&
478 : 20 : ' mlwfovlp : mlwfovlp_setup done -',ch10,&
479 [ + - ]: 40 : '- see ',trim(filew90_wout(isppol)),' for details.'
480 : 39 : call wrtout(units, msg)
481 : : end do
482 : :
483 : : ! some allocations after wannier90 setup
484 [ + + ]: 39 : max_num_bands=maxval(num_bands(:))
485 [ + + ]: 39 : mwan=maxval(nwan(:))
486 [ - + + - : 95 : ABI_MALLOC(eigenvalues_w,(max_num_bands,nkpt,nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
487 [ - + + - : 133 : ABI_MALLOC(M_matrix,(max_num_bands,max_num_bands,nntot,nkpt,nsppol))
- + + - -
+ + - - +
+ - - + +
- + - + -
- + - + -
+ ]
488 [ - + + - : 114 : ABI_MALLOC(A_matrix,(max_num_bands,mwan,nkpt,nsppol))
- + + - -
+ + - - +
+ - + - +
- - + -
+ ]
489 : :
490 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
491 : : !3) Write Eigenvalues (file seed_name.eig)
492 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
493 : : if (leig) then
494 : 19 : call write_eigenvalues(filew90_eig,eigen, band_in, eigenvalues_w, nsppol, nkpt, mband, dtset, rank, master )
495 : : end if !leig
496 : :
497 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
498 : : !4) Calculate overlaps (file seed_name.mmn)
499 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
500 : : !
501 : : !First calculate indices and shift
502 : : !
503 : : !write(std_out,*) "Computes shift for cg"
504 : 19 : write(msg, '(a,a)' ) ch10,' mlwfovlp : compute shifts for g-points '
505 : 19 : call wrtout(std_out, msg)
506 : : !----------------------------------------------------------------------
507 : : !Compute shifts for g points (icg,iwav)
508 : : !(here mband is not used, because shifts are internal variables of abinit)
509 : : !----------------------------------------------------------------------
510 : : !call mywfc%init(cg, cprj, dtset, dtfil, hdr, &
511 : : ! & MPI_enreg, nprocs, psps, pawtab, rank)
512 : :
513 : : !TODO uncomment
514 : : ! call mywfc%kset%set_ovikp( ovikp=ovikp, nntot=nntot, num_nnmax=num_nnmax)
515 : : !
516 : : !Shifts computed.
517 : : !
518 : : if( lmmn) then
519 : : !
520 : : ! In case of parallelization write out cg for all k-points
521 : : !
522 : : !if (nprocs > 1) then
523 : : ! call write_cg_and_cprj(dtset, cg, cprj, dtfil, iwav, npwarr, mband, natom, &
524 : : ! &nsppol, nkpt, MPI_enreg, rank, psps, pawtab)
525 : : ! call mywfc%write_cg_and_cprj_tmpfile()
526 : : !end if !MPI nprocs>1
527 : : !
528 : : ! End of MPI preliminarities
529 : : ! Calculate PW contribution of overlaps
530 : : !
531 [ - + + - : 133 : ABI_MALLOC(cm1,(2,mband,mband,nntot,nkpt,nsppol))
- + + - -
+ + - - +
+ - - + +
- + - + -
- + - + -
+ ]
532 : : ! this loops over spin internally
533 : : call mlwfovlp_pw(mywfc,cm1,g1,kg,mband, mkmem,mpi_enreg,mpw,nfft,ngfft,nkpt,nntot,&
534 : 19 : npwarr,hdr%nspinor,nsppol,ovikp)
535 : :
536 : : !mlwfovlp_pw(mywfc,cm1,g1,kg,mband,mkmem,mpi_enreg,mpw,nfft,ngfft,nkpt,nntot,&
537 : : ! & npwarr,nspinor,nsppol,ovikp,seed_name)
538 : 19 : write(msg, '(a,a)' ) ch10,' mlwfovlp: PW part of overlap computed '
539 : 19 : call wrtout(std_out, msg)
540 : : !
541 : : ! compute PAW Contribution and add it to PW contribution
542 : : !
543 [ + + ]: 19 : if(psps%usepaw==1) then
544 : 5 : write(msg, '(a,a)' ) ch10,'** smatrix_pawinit: PAW part of overlap '
545 : 5 : call wrtout(std_out, msg)
546 [ - + + - : 20 : ABI_MALLOC(cm2_paw,(2,mband,mband))
- + + - +
- + - - +
- + ]
547 [ + + ]: 11 : do isppol=1,nsppol
548 [ + + ]: 283 : do ikpt1=1,nkpt
549 : : ! MPI:cycle over k-points not treated by this node
550 [ - + ]: 272 : if (nprocs>1 ) then !sometimes we can have just one processor
551 [ # # ]: 0 : if ( ABS(MPI_enreg%proc_distrb(ikpt1,1,isppol)-rank) /=0) CYCLE
552 : : end if
553 : :
554 : 272 : write(msg, '(a,i0,a,2(i0,1x))')' processor',rank,' computes PAW part for kpt and spin',ikpt1,isppol
555 : 272 : call wrtout(std_out, msg)
556 : :
557 [ + + ]: 3222 : do intot=1,nntot
558 : 2944 : ikpt2= ovikp(ikpt1,intot)
559 [ + + ]: 11776 : g1temp(:)=g1(:,ikpt1,intot)
560 : : ! TODO : smatrix_pawinit: use high level wfd.
561 : 2944 : cprj_ptr=>mywfc%get_cprj_ptr()
562 : : call smatrix_pawinit(atindx1,cm2_paw,cprj_ptr,ikpt1,ikpt2,isppol,&
563 : : & g1temp,gprimd,hdr%kptns,mband,mband,mkmem,mpi_enreg,&
564 : : & natom,dtset%nband,nkpt,dtset%nspinor,nsppol,dtset%ntypat,pawang,pawrad,pawtab,rprimd,&
565 [ - + - - : 2944 : & dtfil%fnametmp_cprj,dtset%typat,xred)
- - - + -
- - - - +
- + - + ]
566 : : ! cm1(:,:,:,intot,ikpt1,isppol)=four_pi*cm2_paw(:,:,:)
567 : : ! write(6,*) "ikpt1=",ikpt1
568 : : ! do iband=1,mband
569 : : ! write(6,*) "iband=",iband
570 : : ! write(6,*) "Wannier PW overlap",cm1(:,iband,iband,intot,ikpt1,isppol)
571 : : ! write(6,*) "Wannier PAW overlap",four_pi*cm2_paw(:,iband,iband)
572 : : ! write(6,*) "Wannier PW+PAW overlap",cm1(:,iband,iband,intot,ikpt1,isppol)+four_pi*cm2_paw(:,iband,iband)
573 : : ! enddo
574 [ + + + + : 2473744 : cm1(:,:,:,intot,ikpt1,isppol)=cm1(:,:,:,intot,ikpt1,isppol)+four_pi*cm2_paw(:,:,:)
+ + ]
575 : : end do ! intot
576 : : end do ! ikpt1
577 : : end do ! isppol
578 [ - + ]: 5 : ABI_FREE(cm2_paw)
579 : 5 : write(msg, '(a,a)' ) ch10,' mlwfovlp : PAW part of overlap computed '
580 : 5 : call wrtout(std_out, msg)
581 : : end if ! usepaw
582 : :
583 : 19 : call xmpi_sum(cm1,comm,ierr)
584 : :
585 : : call write_Mmn(filew90_mmn, band_in, cm1, ovikp, g1, M_matrix, nkpt, nsppol, nntot, mband, num_bands, msg, &
586 : 19 : iam_master=(rank==master), test_matrix_output=test_matrix_output)
587 [ - + ]: 38 : ABI_FREE(cm1)
588 : :
589 : : ! erase temporary files created for parallel runs
590 : : !if (nprocs > 1) call mywfc%remove_tmpfile(prtvol)
591 : : !end if !MPI nprocs>1
592 : : end if !lmmn
593 : :
594 : : !Deallocate arrays no longer needed
595 [ - + ]: 19 : ABI_FREE(ovikp)
596 [ - + ]: 19 : ABI_FREE(g1)
597 : :
598 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
599 : : !5) Calculate initial projections
600 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
601 : :
602 [ + - ]: 19 : if (dtset%w90iniprj/=0) then
603 : :
604 : : ! Set value for lproj (type of projections to be computed)
605 : : ! In PAW, options 5 and 6 are not in use.
606 : : ! 5 means that there will be a contribution from inside the spheres and another from the PW part
607 : : ! 6 means that we take into account just the inside-spheres contribution
608 : : ! 2 means that PW part will be calculated
609 : 19 : lproj=dtset%w90iniprj
610 [ - + ]: 19 : if(dtset%w90iniprj == 5 ) lproj=2 ! Necessary to calculate PW contribution
611 [ - + + - : 76 : ABI_MALLOC(just_augmentation,(mwan,nsppol))
- + + - +
- + - - +
- + ]
612 [ + + + + ]: 151 : just_augmentation(:,:)=.false.
613 : :
614 [ + + + + ]: 19 : if( psps%usepaw==1 .and. (dtset%w90iniprj==2 .or. dtset%w90iniprj>4)) then
615 [ - + - - : 4 : if (dtset%w90iniprj==6) just_augmentation(:,:)=.true.
- - ]
616 [ - + ]: 4 : if (dtset%w90iniprj==5) then
617 [ # # ]: 0 : do isppol=1,nsppol
618 [ # # ]: 0 : do iwan=1,nwan(isppol)
619 : : ! Trick to skip the planewave contribution for some Wannier functions
620 : : ! (Not in production).
621 [ # # ]: 0 : if(proj_radial(iwan,isppol) > 4) then
622 : 0 : just_augmentation(iwan,isppol)=.true.
623 : 0 : proj_radial(iwan,isppol)=proj_radial(iwan,isppol)-3
624 : 0 : write(msg, '(2a,2(i0,1x))')' ','Skiping planewave contribution for iwan, ispin=',iwan,isppol
625 : 0 : call wrtout(std_out, msg)
626 : : end if !proj_radial>4
627 : : end do !iwan
628 : : end do !isppol
629 : : end if !w90iniprj == 5
630 : : end if !paw
631 : : !
632 : : ! Call mlwfovlp_proj (plane waves part of projections)
633 : : !
634 [ + - ]: 19 : if (dtset%w90iniprj/=6) then ! option 6 not yet in use
635 : : ! call mlwfovlp_proj(A_matrix,band_in,cg,cprj,dtset,gprimd,just_augmentation,kg,&
636 : : !& lproj,max_num_bands,mband,mkmem,mpi_enreg,mpw,mwan,natom,&
637 : : !& nattyp,nkpt,npwarr,&
638 : : !& dtset%nspinor,nsppol,ntypat,num_bands,nwan,pawtab,proj_l,proj_m,&
639 : : !& proj_radial,proj_site,proj_x,proj_z,proj_zona,psps,ucvol)
640 : : call mlwfovlp_proj(A_matrix,band_in,mywfc,dtset,gprimd,just_augmentation,kg,&
641 : : & lproj,max_num_bands,mband,mkmem,mpi_enreg,mpw,mwan,natom,&
642 : : & nattyp,nkpt,npwarr,&
643 : : & dtset%nspinor,nsppol,ntypat,num_bands,nwan,pawtab,proj_l,proj_m,&
644 [ - + ]: 19 : & proj_radial,proj_site,proj_x,proj_z,proj_zona,psps,ucvol)
645 : 19 : write(msg, '(a,a,a,a)' ) ch10,&
646 : 19 : ' mlwfovlp: mlwfovlp_proj done -',ch10,&
647 : 38 : ' Projectors computed.'
648 : 19 : call wrtout(std_out, msg)
649 : : end if !w90proj/=6
650 : : !
651 : : ! Calculate inside-sphere part of projections (PAW)
652 : : !
653 [ + + - + ]: 19 : if (psps%usepaw ==1 .and. ( dtset%w90iniprj>4)) then
654 [ # # # # : 0 : ABI_MALLOC(A_paw,(max_num_bands,mwan,nkpt,nsppol))
# # # # #
# # # # #
# # # # #
# # # #
# ]
655 : : call mlwfovlp_projpaw(A_paw,band_in,mywfc,just_augmentation,max_num_bands,mband,mkmem,&
656 : : & mwan,natom,dtset%nband,nkpt,&
657 : : & dtset%nspinor,nsppol,dtset%ntypat,nwan,pawrad,pawtab,&
658 : : & proj_l,proj_m,proj_radial,proj_site,proj_x,proj_z,proj_zona,psps,&
659 [ # # # # : 0 : & rprimd,dtset%typat,xred)
# # # # #
# # # # #
# # ]
660 : : !
661 : 0 : write(msg, '(a,a,a,a)' ) ch10,&
662 : 0 : ' mlwfovlp: mlwfovlp_proj_paw done -',ch10,&
663 : 0 : ' Inside-spheres part of projectors computed.'
664 : 0 : call wrtout(std_out, msg)
665 : : !
666 : : ! Add in-sphere contribution to A_matrix
667 : : !
668 : : !
669 : : ! w90iniprj==5. Plane waves + augmentation contributions
670 : : !
671 [ # # # # : 0 : if(dtset%w90iniprj==5) A_matrix(:,:,:,:)=A_matrix(:,:,:,:)+A_paw(:,:,:,:)
# # # # #
# ]
672 : : !
673 : : ! w90iniprj==6. Just augmentation contribution
674 : : !
675 [ # # # # : 0 : if(dtset%w90iniprj==6) A_matrix(:,:,:,:)=A_paw(:,:,:,:)
# # # # #
# ]
676 [ # # ]: 0 : ABI_FREE(A_paw)
677 : : end if !usepaw==1
678 : :
679 [ - + ]: 19 : ABI_FREE(just_augmentation)
680 : 19 : call xmpi_sum(A_matrix,comm,ierr)
681 : :
682 : : ! write projections to file
683 [ + - ]: 19 : if (rank==master) then
684 [ + + ]: 19 : if(dtset%w90iniprj==1) then
685 : 6 : call write_Amn(A_matrix, filew90_ramn, nsppol, mband, nkpt, num_bands, nwan, band_in, test_matrix_output)
686 : : else
687 : 13 : call write_Amn(A_matrix, filew90_amn, nsppol, mband, nkpt, num_bands, nwan, band_in, test_matrix_output)
688 : : end if
689 : : end if
690 : : end if !dtset%w90iniprj/=0
691 : :
692 : : ! Deallocations
693 [ - + ]: 19 : ABI_FREE(proj_site)
694 [ - + ]: 19 : ABI_FREE(proj_l)
695 [ - + ]: 19 : ABI_FREE(proj_m)
696 [ - + ]: 19 : ABI_FREE(proj_radial)
697 [ - + ]: 19 : ABI_FREE(proj_x)
698 [ - + ]: 19 : ABI_FREE(proj_z)
699 [ - + ]: 19 : ABI_FREE(proj_zona)
700 [ - + ]: 19 : ABI_FREE(proj_s_loc)
701 [ - + ]: 19 : ABI_FREE(proj_s_qaxis_loc)
702 : :
703 : :
704 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
705 : : !6) write files for wannier function plot
706 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
707 [ + + ]: 19 : if( dtset%w90prtunk>0) then
708 : : call compute_and_write_unk(wfnname, psps%usepaw, dtset%w90prtunk, &
709 : : mpi_enreg, ngfft, nsppol, dtset%nspinor, &
710 : : nkpt, mband, mpw, mgfftc, mkmem, nprocs, rank, npwarr, &
711 : 4 : band_in, dtset, kg, mywfc)
712 : : end if
713 : :
714 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
715 : : !7) Call to Wannier90
716 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
717 : : if (lwannierrun) then
718 [ - + ]: 19 : if (lwanniersetup.ne.1) ABI_ERROR("lwanniersetup.ne.1")
719 [ - + + - : 114 : ABI_MALLOC(U_matrix,(mwan,mwan,nkpt,nsppol))
- + + - -
+ + - - +
+ - + - +
- - + - +
- + ]
720 [ - + + - : 114 : ABI_MALLOC(U_matrix_opt,(max_num_bands,mwan,nkpt,nsppol))
- + + - -
+ + - - +
+ - + - +
- - + - +
- + ]
721 [ - + + - : 95 : ABI_MALLOC(lwindow,(max_num_bands,nkpt,nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
722 [ - + + - : 76 : ABI_MALLOC(wann_centres,(3,mwan,nsppol))
- + + - +
- + - - +
- + - + ]
723 [ - + + - : 76 : ABI_MALLOC(wann_spreads,(mwan,nsppol))
- + + - +
- + - - +
- + - + ]
724 : : ! Initialize
725 [ + + + + : 48135 : U_matrix(:,:,:,:)=czero
+ + + + ]
726 [ + + + + : 65031 : U_matrix_opt(:,:,:,:)=czero
+ + + + ]
727 [ + + + + : 7399 : lwindow(:,:,:)=.false.
+ + ]
728 [ + + + + : 487 : wann_centres(:,:,:)=zero
+ + ]
729 [ + + + + ]: 151 : wann_spreads(:,:)=zero
730 : : ! write(std_out,*) seed_name; write(std_out,*) ngkpt
731 [ - + ]: 19 : ABI_CHECK(isdiagmat(dtset%kptrlatt), "kptrlatt should be diagonal! Please use nkgpt with one shift")
732 : 19 : ngkpt(1)=dtset%kptrlatt(1,1)
733 : 19 : ngkpt(2)=dtset%kptrlatt(2,2)
734 : 19 : ngkpt(3)=dtset%kptrlatt(3,3)
735 : :
736 : : ! write(std_out,*) nkpt
737 : : ! write(std_out,*) rprimd*Bohr_Ang
738 : : ! write(std_out,*) two_pi*gprimd/Bohr_Ang
739 : : ! write(std_out,*) mband
740 : : ! write(std_out,*) "nwan",nwan
741 : : ! write(std_out,*) nntot
742 : : ! write(std_out,*) natom
743 : : ! write(std_out,*) atom_symbols
744 : : ! write(std_out,*) xcart
745 : : ! write(std_out,*) num_bands,num_bands,nntot,nkpt
746 : : ! write(std_out,*) wann_spreads
747 : : ! wann_spreads=2
748 : : ! do i=1, nkpt
749 : : ! do j=1, nntot
750 : : ! write(std_out,*) i,j
751 : : ! do k=1, num_bands
752 : : ! do l=1, num_bands
753 : : ! write(std_out,*) "m",M_matrix(l,k,j,i,1)
754 : : ! enddo
755 : : ! enddo
756 : : ! enddo
757 : : ! enddo
758 : :
759 : : #if defined HAVE_WANNIER90
760 [ + + ]: 39 : do isppol=1,nsppol
761 : : ! when nsppol>1, master runs isppol 1 and rank==1 runs isppol 2
762 [ - + - - : 20 : if(nprocs>1 .and. isppol==1.and.rank.ne.master) cycle
- - ]
763 [ - + - - : 20 : if(nprocs>1 .and. isppol==2.and.rank.ne.1) cycle
- - ]
764 : :
765 : 20 : write(msg, '(8a)' ) ch10,&
766 : 20 : '** mlwfovlp: calling wannier90 library subroutine wannier_run ',ch10,&
767 : 20 : ' Calculation is running ',ch10,&
768 [ + - ]: 40 : '- see ',trim(filew90_wout(isppol)),' for details.'
769 : 20 : call wrtout(units, msg)
770 : :
771 : 20 : write(msg, '(a,i0)') ' Spin channel: ', isppol
772 : 20 : call wrtout(units, msg)
773 : 20 : write(msg, '(a,3(i0,1x))') ' Uniform k-mesh: ', ngkpt
774 : 20 : call wrtout(units, msg)
775 : 20 : write(msg, '(a,i0)') ' Number of k-points: ', nkpt
776 : 20 : call wrtout(units, msg)
777 : 20 : write(msg, '(a,i0)') ' Number of input bands: ', num_bands(isppol)
778 : 20 : call wrtout(units, msg)
779 : 20 : write(msg, '(a,i0)') ' Number of Wannier functions: ', nwan(isppol)
780 : 20 : call wrtout(units, msg)
781 : 20 : write(msg, '(a,i0)') ' Number of k-point neighbours: ', nntot
782 : 20 : call wrtout(units, msg)
783 : 20 : write(msg, '(a,es16.8)') ' Fermi energy [eV]: ', ebands%fermie * Ha_eV
784 : 20 : call wrtout(units, msg)
785 : 20 : write(msg, '(a,2(es16.8,1x))') ' Eigenvalue range (min, max) [eV]: ', &
786 [ + + + + : 18504 : minval(ebands%eig(:,:,isppol)) * Ha_eV, maxval(ebands%eig(:,:,isppol)) * Ha_eV
+ + + - -
+ - - + +
+ + + + +
- - + -
- ]
787 : 20 : call wrtout(units, msg)
788 : :
789 : : call wannier_run(trim(seed_name(isppol)),ngkpt,nkpt,& ! input
790 : : real_lattice,recip_lattice,hdr%kptns,num_bands(isppol),& ! input
791 : : nwan(isppol),nntot,natom,atom_symbols,& ! input
792 : : xcart*Bohr_Ang,gamma_only,M_matrix(:,:,:,:,isppol),A_matrix(:,:,:,isppol),eigenvalues_w(:,:,isppol),& ! input
793 : : U_matrix(1:nwan(isppol),1:nwan(isppol),:,isppol),& ! output
794 : : U_matrix_opt(1:num_bands(isppol),1:nwan(isppol),:,isppol),& ! output
795 : : lwindow_loc=lwindow(1:num_bands(isppol),:,isppol),& ! output
796 : : wann_centres_loc=wann_centres(:,1:nwan(isppol),isppol),& ! output
797 [ + - + + : 164 : wann_spreads_loc=wann_spreads(1:nwan(isppol),isppol),spread_loc=spreadw(:,isppol)) ! output
+ + - + -
- - + - -
- + - - +
- - + - +
- - - - -
- - + - -
- - - - -
+ - - -
- ]
798 : :
799 : 20 : write(msg, '(a)') ' Wannier90 physical results:'
800 : 20 : call wrtout(units, msg)
801 : 20 : write(msg, '(a,3(es16.8,1x))') '- Spreads (Omega_total, Omega_I, Omega_tilde) [Ang^2]: ', &
802 : 40 : spreadw(:,isppol)
803 : 20 : call wrtout(units, msg)
804 : 20 : write(msg, '(a)') ' Wannier function centres [Ang] and spreads [Ang^2]:'
805 : 20 : call wrtout(units, msg)
806 [ + + ]: 132 : do iwan=1,nwan(isppol)
807 : 112 : write(msg, '(a,i0,a,3(f14.8,1x),a,f14.8)') '- WF ', iwan, ': centre = ', &
808 : 224 : wann_centres(:,iwan,isppol), ' spread = ', wann_spreads(iwan,isppol)
809 : 132 : call wrtout(units, msg)
810 : : end do
811 : :
812 : 20 : write(msg, '(7a)' ) ch10,&
813 [ + - ]: 40 : ' mlwfovlp : mlwfovlp_run completed -',ch10,'- see ',trim(filew90_wout(isppol)),' for details.',ch10
814 : 39 : call wrtout(units, msg)
815 : : end do !isppol
816 : :
817 : : ! collect output of wannier90 from different processors
818 : 19 : call xmpi_sum(U_matrix,comm,ierr)
819 : 19 : call xmpi_sum(U_matrix_opt,comm,ierr)
820 : 19 : call xmpi_lor(lwindow,comm)
821 : 19 : call xmpi_sum(wann_centres,comm,ierr)
822 : 19 : call xmpi_sum(wann_spreads,comm,ierr)
823 : :
824 : : ! Output ABIWAN.nc file
825 [ + + ]: 19 : if (hdr%kptopt == 0) then
826 : 4 : ABI_WARNING("Output of ABIWAN.nc requires kptopt /= 0. ABIWAN.nc file won't be produced!")
827 : : ! Need kptrlatt in wigner_seitz and client code needs to know the k-grid.
828 : : end if
829 : :
830 [ + - + + ]: 19 : if (rank == master .and. hdr%kptopt /= 0) then
831 [ + - ]: 15 : abiwan_fname = strcat(dtfil%filnam_ds(4), "_ABIWAN.nc")
832 : 15 : call wrtout(std_out, sjoin(" Saving wannier90 ouput results to:", abiwan_fname))
833 : : call wigner_seitz([zero, zero, zero], [2, 2, 2], dtset%kptrlatt, crystal%rmet, &
834 [ - + - + : 15 : nrpts, irvec_r_h, ndegen_h, rmods_r_h, prtvol=prtvol)
- + ]
835 : : ! We know if disentanglement has been done by looking at the output values of lwindow
836 : : ! Not elegant but it is the only way to avoid the parsing of the wannier input.
837 : : ! In wannier_run lwindow is set to True if not disentanglement
838 [ + + ]: 31 : have_disentangled_spin = 0
839 [ + + ]: 31 : do isppol=1,nsppol
840 : : !if nwan(isppol) < num_bands(isppol)
841 [ + + + + : 4342 : if (.not. all(lwindow(:,:,isppol))) have_disentangled_spin(isppol) = 1
+ + + + ]
842 : : end do
843 : :
844 [ - + ]: 15 : NCF_CHECK(nctk_open_create(ncid, abiwan_fname, xmpi_comm_self))
845 [ - + ]: 15 : NCF_CHECK(hdr%ncwrite(ncid, fform_from_ext("ABIWAN"), nc_define=.True.))
846 [ - + ]: 15 : NCF_CHECK(crystal%ncwrite(ncid))
847 [ - + ]: 15 : NCF_CHECK(ebands%ncwrite(ncid))
848 : :
849 : : ncerr = nctk_def_dims(ncid, [ &
850 : : nctkdim_t("mwan", mwan), &
851 : : nctkdim_t("max_num_bands", max_num_bands), &
852 : : nctkdim_t("nrpts", nrpts) &
853 [ + + ]: 60 : ], defmode=.True.)
854 [ - + ]: 15 : NCF_CHECK(ncerr)
855 : :
856 [ + + ]: 30 : ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "nntot"])
857 [ - + ]: 15 : NCF_CHECK(ncerr)
858 : : !ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "fermi_energy", "smearing_width"])
859 : : !NCF_CHECK(ncerr)
860 : :
861 : : ncerr = nctk_def_arrays(ncid, [ &
862 : : nctkarr_t("nwan", "int", "number_of_spins"), &
863 : : nctkarr_t("num_bands", "int", "number_of_spins"), &
864 : : nctkarr_t("band_in_int", "int", "max_number_of_states, number_of_spins"), &
865 : : nctkarr_t("lwindow_int", "int", "max_num_bands, number_of_kpoints, number_of_spins"), &
866 : : nctkarr_t("exclude_bands", "int", "max_number_of_states, number_of_spins"), &
867 : : nctkarr_t("spread", "dp", "three, number_of_spins"), &
868 : : !nctkarr_t("A_matrix", "dp", "two, max_num_bands, mwan, number_of_kpoints, number_of_spins"), &
869 : : nctkarr_t("irvec", "int", "three, nrpts"), &
870 : : nctkarr_t("ndegen", "int", "nrpts"), &
871 : : nctkarr_t("have_disentangled_spin", "int", "number_of_spins"), &
872 : : nctkarr_t("U_matrix", "dp", "two, mwan, mwan, number_of_kpoints, number_of_spins"), &
873 : : nctkarr_t("U_matrix_opt", "dp", "two, max_num_bands, mwan, number_of_kpoints, number_of_spins"), &
874 : : nctkarr_t("wann_centres", "dp", "three, mwan, number_of_spins"), &
875 : : nctkarr_t("wann_spreads", "dp", "mwan, number_of_spins") &
876 [ + + ]: 210 : ])
877 [ - + ]: 15 : NCF_CHECK(ncerr)
878 : :
879 : : ! Write data.
880 [ - + ]: 15 : NCF_CHECK(nctk_set_datamode(ncid))
881 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nntot"), nntot))
882 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nwan"), nwan))
883 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "num_bands"), num_bands))
884 [ + - - + : 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "band_in_int"), l2int(band_in)))
- - ]
885 [ + - - + : 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "lwindow_int"), l2int(lwindow)))
- - ]
886 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "exclude_bands"), exclude_bands))
887 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "spread"), spreadw))
888 : : !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "A_matrix"), c2r(A_matrix)))
889 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "irvec"), irvec_r_h))
890 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ndegen"), ndegen_h))
891 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "have_disentangled_spin"), have_disentangled_spin))
892 [ + - - + : 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "U_matrix"), c2r(U_matrix)))
- - ]
893 [ + - - + : 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "U_matrix_opt"), c2r(U_matrix_opt)))
- - ]
894 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "wann_centres"), wann_centres))
895 [ - + ]: 15 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "wann_spreads"), wann_spreads))
896 [ - + ]: 15 : NCF_CHECK(nf90_close(ncid))
897 : :
898 [ - + ]: 15 : ABI_FREE(irvec_r_h)
899 [ - + ]: 15 : ABI_FREE(ndegen_h)
900 [ - + ]: 15 : ABI_FREE(rmods_r_h)
901 : : end if
902 : :
903 : : ! CALL SILVESTRELLI'S APPROACH TO EVALUATE vdW INTERACTION ENERGY USING MLWF!!
904 : : ! ----------------------------------------------------------------------------------------------
905 [ + + + + : 19 : if (dtset%vdw_xc==10.or.dtset%vdw_xc==11.or.dtset%vdw_xc==12.or.dtset%vdw_xc==14.and.rank==master) then
+ - ]
906 : : ! vdw_xc==10,11,12,14 starts the vdW interaction using MLWFs
907 : 3 : call evaluate_vdw_with_mlwf()
908 : : end if
909 : :
910 : : #else
911 : : ABI_UNUSED(occ)
912 : : #endif
913 [ - + ]: 19 : ABI_FREE(wann_centres)
914 [ - + ]: 19 : ABI_FREE(wann_spreads)
915 [ - + ]: 19 : ABI_FREE(U_matrix)
916 [ - + ]: 19 : ABI_FREE(U_matrix_opt)
917 [ - + ]: 57 : ABI_FREE(lwindow)
918 : : end if !lwannierrun
919 : :
920 [ - + ]: 19 : ABI_FREE(band_in)
921 [ - + ]: 19 : ABI_FREE(atom_symbols)
922 [ - + ]: 19 : ABI_FREE(xcart)
923 [ - + ]: 19 : ABI_FREE(eigenvalues_w)
924 [ - + ]: 19 : ABI_FREE(M_matrix)
925 [ - + ]: 19 : ABI_FREE(A_matrix)
926 : : !ABI_FREE(exclude_bands)
927 : :
928 : 19 : call mywfc%free()
929 [ - + + - : 57 : ABI_FREE_SCALAR(mywfc)
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + -
+ ]
930 : :
931 : : contains
932 : : !!***
933 : :
934 : : !--------------------------------------------------------------------------------
935 : : !> van der Waals interaction energy using MLWFs
936 : : !--------------------------------------------------------------------------------
937 : 3 : subroutine evaluate_vdw_with_mlwf()
938 : : #ifdef HAVE_WANNIER90
939 : : integer :: ii, jj, ikpt, iband, kk
940 : : real(dp) :: corrvdw
941 : : complex(dp) :: caux,caux2,caux3
942 : 3 : real(dp),allocatable :: csix(:,:,:,:)
943 : 3 : real(dp),allocatable :: occ_arr(:,:,:),occ_wan(:,:,:)
944 : 3 : real(dp),allocatable :: tdocc_wan(:,:)
945 : :
946 : 3 : write(std_out,*) 'nwan(nsppol)=',ch10
947 [ + + ]: 6 : do ii=1,nsppol
948 : 6 : write(std_out,*) 'nsppol=',ii, 'nwan(nsppol)=',nwan(ii),ch10
949 : : end do
950 : 3 : write(std_out,*) 'mwan=', mwan, ch10
951 : :
952 [ - + + - : 15 : ABI_MALLOC(occ_arr,(mband,nkpt,isppol))
- + + - -
+ + - + -
+ - - + -
+ ]
953 [ - + + - : 15 : ABI_MALLOC(occ_wan,(mwan,nkpt,nsppol))
- + + - -
+ + - + -
+ - - + -
+ ]
954 [ - + + - : 12 : ABI_MALLOC(tdocc_wan,(mwan,nsppol))
- + + - +
- + - - +
+ - ]
955 : :
956 [ + + + + : 249 : occ_arr(:,:,:)=zero
+ + ]
957 [ + + + + : 126 : occ_wan(:,:,:)=zero
+ + ]
958 [ + + + + ]: 18 : tdocc_wan(:,:)=zero
959 : 3 : jj = 0
960 [ + + ]: 6 : do isppol=1,nsppol
961 [ + + ]: 30 : do ikpt=1,nkpt
962 [ + + ]: 123 : do iband=1,num_bands(isppol)
963 : 96 : jj = jj + 1
964 : 120 : occ_arr(iband,ikpt,isppol) = occ(jj)
965 : : end do
966 : : end do
967 : : end do
968 : :
969 [ + + ]: 6 : do isppol=1,nsppol
970 [ + + ]: 30 : do ikpt=1,nkpt
971 [ + + ]: 123 : do iwan=1,nwan(isppol)
972 : 96 : caux=czero
973 : 96 : caux2=czero
974 : 96 : caux3=czero
975 [ + + ]: 480 : do iband=1,num_bands(isppol) !nband_inc(isppol) !nwan(isppol)
976 [ + + ]: 2016 : do ii=1,nwan(isppol)
977 : 1536 : caux=U_matrix(ii,iwan,ikpt,isppol)*U_matrix_opt(iband,ii,ikpt,isppol)
978 : : ! DEBUG
979 : : ! if(ISNAN(dble(caux))) then
980 : : ! write(std_out,*) 'NaN: caux(ikpt,iwan,iband,ii):',ikpt,iwan,iband,ii,ch10
981 : : ! end if
982 : : ! END DEBUG
983 [ + + ]: 8064 : do kk=1,nwan(isppol)
984 : 6144 : caux2=conjg(U_matrix(kk,iwan,ikpt,isppol))*conjg(U_matrix_opt(iband,kk,ikpt,isppol))
985 : 7680 : caux3= caux3+caux*caux2*occ_arr(iband,ikpt,isppol) !take care here as exclude_bands case is not well
986 : : ! DEBUG
987 : : ! if(ISNAN(dble(caux2))) then
988 : : ! write(std_out,*) 'NaN: caux2(ikpt,iwan,iband,kk):',ikpt,iwan,iband,kk,ch10
989 : : ! end if
990 : : ! if(ISNAN(dble(caux3))) then
991 : : ! write(std_out,*) 'NaN: caux3(ikpt,iwan,iband,kk,jj):',ikpt,iwan,iband,kk,jj
992 : : ! end if
993 : : ! END DEBUG
994 : : end do
995 : : end do
996 : : end do
997 : 120 : occ_wan(iwan,ikpt,isppol) = dble(caux3)
998 : : ! DEBUG
999 : : ! write(std_out,*) occ_wan(iwan,ikpt,isppol)
1000 : : ! END DEBUG
1001 : : ! end do
1002 : : end do
1003 : : end do
1004 : : end do
1005 : :
1006 : 3 : write(std_out,*) ch10,'MLWFs Occupation Matrix diagonal terms:',ch10
1007 : :
1008 [ + + ]: 6 : do jj=1,nsppol
1009 [ + + + + ]: 111 : forall(iwan=1:nwan(jj)) tdocc_wan(iwan,jj) = sum(occ_wan(iwan,1:nkpt,jj)) / real(nkpt,dp)
1010 : 3 : write(std_out,*) 'tdocc_wan(iwan),isppol:',ch10
1011 : 6 : write(std_out,*) (tdocc_wan(iwan,jj),iwan=1,nwan(jj)),jj
1012 : : end do
1013 : :
1014 [ - + + - : 18 : ABI_MALLOC(csix,(mwan,mwan,nsppol,nsppol))
- + + - -
+ + - - +
+ - + - +
- - + -
+ ]
1015 : :
1016 : : call evdw_wannier(csix,corrvdw,mwan,natom,nsppol,nwan,tdocc_wan,dtset%vdw_nfrag,&
1017 : 3 : dtset%vdw_supercell,dtset%vdw_typfrag,dtset%vdw_xc,rprimd,wann_centres,wann_spreads,xcart)
1018 : :
1019 [ - + ]: 3 : ABI_FREE(csix)
1020 [ - + ]: 3 : ABI_FREE(occ_arr)
1021 [ - + ]: 3 : ABI_FREE(occ_wan)
1022 [ - + ]: 3 : ABI_FREE(tdocc_wan)
1023 : :
1024 : : #endif
1025 : 3 : end subroutine evaluate_vdw_with_mlwf
1026 : :
1027 : : end subroutine mlwfovlp
1028 : : !!***
1029 : :
1030 : : !!****f* m_mlwfovlp/mlwfovlp_seedname
1031 : : !! NAME
1032 : : !! mlwfovlp_seedname
1033 : : !!
1034 : : !! FUNCTION
1035 : : !! Get seed name and file names of all wannier90 related files
1036 : : !!
1037 : : !! INPUTS
1038 : : !! fname_w90=root name of file appended with _w90
1039 : : !!
1040 : : !! OUTPUT
1041 : : !! filew90_win= main input file for Wannier90
1042 : : !! filew90_wout= main output file for Wannier90
1043 : : !! filew90_amn= file containing Amn matrix
1044 : : !! filew90_ramn= file containing Amn matrix (random initial projections)
1045 : : !! filew90_mmn= file containing Mmn matrix
1046 : : !! filew90_eig= file containing eigenvalues
1047 : : !! nsppol= number of spin polarizations
1048 : : !! seed_name= common seed name for all wannier90 related files
1049 : : !!
1050 : : !! SOURCE
1051 : :
1052 : 19 : subroutine mlwfovlp_seedname(fname_w90,filew90_win,filew90_wout,filew90_amn,&
1053 : 19 : & filew90_ramn,filew90_mmn,filew90_eig,nsppol,seed_name)
1054 : :
1055 : : !Arguments ------------------------------------
1056 : : integer,intent(in) :: nsppol
1057 : : character(len=fnlen),intent(out) :: filew90_win(nsppol),filew90_wout(nsppol),filew90_amn(nsppol),filew90_ramn(nsppol)
1058 : : character(len=fnlen),intent(out) :: filew90_mmn(nsppol),filew90_eig(nsppol),seed_name(nsppol)
1059 : : character(len=fnlen),intent(in) :: fname_w90
1060 : :
1061 : : !Local variables-------------------------------
1062 : : integer:: isppol, units(2)
1063 : : character(len=fnlen) :: test_win1,test_win2,test_win3
1064 : : logical :: lfile
1065 : : character(len=2000) :: msg
1066 : : character(len=10):: postfix
1067 : : ! *************************************************************************
1068 : :
1069 [ + + ]: 57 : units = [std_out, ab_out]
1070 [ + + ]: 39 : seed_name(:)=trim(fname_w90)
1071 : :
1072 [ + + ]: 39 : do isppol=1,nsppol
1073 [ + + ]: 20 : if(nsppol==1) postfix='.win'
1074 [ + + + + ]: 20 : if(nsppol==2 .and. isppol==1) postfix='_up.win'
1075 [ + + + + ]: 20 : if(nsppol==2 .and. isppol==2) postfix='_down.win'
1076 : :
1077 [ + - + - ]: 20 : filew90_win(isppol) = trim(seed_name(isppol))//trim(postfix)
1078 : 20 : test_win1 = filew90_win(isppol)
1079 : 20 : inquire(file=filew90_win(isppol),exist=lfile)
1080 : :
1081 [ + + ]: 20 : if(.not.lfile) then
1082 : 4 : seed_name(isppol)='wannier90'
1083 [ + - + - ]: 4 : filew90_win(isppol)=trim(seed_name(isppol))//trim(postfix)
1084 : 4 : test_win2=filew90_win(isppol)
1085 : 4 : inquire(file=filew90_win(isppol),exist=lfile)
1086 : : end if
1087 : :
1088 [ + + ]: 20 : if(.not.lfile) then
1089 : 3 : seed_name(isppol)='w90'
1090 [ + - + + : 9 : filew90_win=trim(seed_name(isppol))//trim(postfix)
+ - ]
1091 : 3 : test_win3=filew90_win(isppol)
1092 : 3 : inquire(file=filew90_win(isppol),exist=lfile)
1093 : : end if
1094 : :
1095 [ - + ]: 39 : if(.not. lfile) then
1096 : : write(msg,'(12a)')&
1097 : 0 : ' wannier90 interface needs one of the following input files:',ch10,&
1098 : 0 : ' ',trim(test_win1),ch10,&
1099 : 0 : ' ',trim(test_win2),ch10,&
1100 : 0 : ' ',trim(test_win3),ch10,&
1101 : 0 : ' Action: read wannier90 tutorial and/or user manual and supply proper *.win file'
1102 : 0 : ABI_ERROR(msg)
1103 : : end if
1104 : : end do !isppol
1105 : :
1106 : : ! Files having different names for different spin polarizations
1107 [ + + ]: 19 : if(nsppol==1) then
1108 [ + - + - ]: 18 : filew90_win(1) =trim(seed_name(1))//'.win'
1109 [ + - + - ]: 18 : filew90_wout(1)=trim(seed_name(1))//'.wout'
1110 [ + - + - ]: 18 : filew90_ramn(1)=trim(seed_name(1))//'random.amn'
1111 [ + - + - ]: 18 : filew90_amn(1) =trim(seed_name(1))//'.amn'
1112 [ + - + - ]: 18 : filew90_mmn(1) =trim(seed_name(1))//'.mmn'
1113 [ + - + - ]: 18 : filew90_eig(1) =trim(seed_name(1))//'.eig'
1114 [ + - ]: 1 : elseif(nsppol==2) then
1115 [ + - + - ]: 1 : filew90_win(1) =trim(seed_name(1))//'_up.win'
1116 [ + - + - ]: 1 : filew90_win(2) =trim(seed_name(2))//'_down.win'
1117 [ + - + - ]: 1 : filew90_wout(1)=trim(seed_name(1))//'_up.wout'
1118 [ + - + - ]: 1 : filew90_wout(2)=trim(seed_name(2))//'_down.wout'
1119 [ + - + - ]: 1 : filew90_ramn(1)=trim(seed_name(1))//'random_up.amn'
1120 [ + - + - ]: 1 : filew90_ramn(2)=trim(seed_name(2))//'random_down.amn'
1121 [ + - + - ]: 1 : filew90_amn(1)=trim(seed_name(1))//'_up.amn'
1122 [ + - + - ]: 1 : filew90_amn(2)=trim(seed_name(2))//'_down.amn'
1123 [ + - + - ]: 1 : filew90_mmn(1)=trim(seed_name(1))//'_up.mmn'
1124 [ + - + - ]: 1 : filew90_mmn(2)=trim(seed_name(2))//'_down.mmn'
1125 [ + - + - ]: 1 : filew90_eig(1)=trim(seed_name(1))//'_up.eig'
1126 [ + - + - ]: 1 : filew90_eig(2)=trim(seed_name(2))//'_down.eig'
1127 : : end if
1128 : :
1129 : : ! change also seed_name for nsppol=2
1130 [ + + ]: 19 : if(nsppol==2) then
1131 [ + - + - ]: 1 : seed_name(1)=trim(seed_name(1))//'_up'
1132 [ + - + - ]: 1 : seed_name(2)=trim(seed_name(2))//'_down'
1133 : : end if
1134 : :
1135 : 19 : write(msg, '(a,a)' ) ch10,'---------------------------------------------------------------'
1136 : 19 : call wrtout(units, msg)
1137 : 19 : write(msg, '(5a)' ) ch10,&
1138 : 19 : ' Calculation of overlap and call to wannier90 library ',ch10,&
1139 : 38 : ' to obtain maximally localized wannier functions ',ch10
1140 : 19 : call wrtout(units, msg)
1141 : :
1142 [ + + ]: 19 : if(nsppol==1) then
1143 : : write(msg, '(23a)' ) &
1144 [ + - ]: 18 : ' - ',trim(filew90_win(1)),' is a mandatory secondary input',ch10,&
1145 [ + - ]: 18 : ' - ',trim(filew90_wout(1)),' is the output for the library',ch10,&
1146 [ + - ]: 18 : ' - ',trim(filew90_ramn(1)),' contains random projections',ch10,&
1147 [ + - ]: 18 : ' - ',trim(filew90_amn(1)),' contains projections',ch10,&
1148 [ + - ]: 18 : ' - ',trim(filew90_mmn(1)),' contains the overlap',ch10,&
1149 [ + - ]: 36 : ' - ',trim(filew90_eig(1)),' contains the eigenvalues'
1150 [ + - ]: 1 : else if(nsppol==2) then
1151 : : write(msg, '(41a)' ) &
1152 [ + - ]: 1 : ' - ',trim(filew90_win(1)),&
1153 [ + - ]: 1 : ' and ',trim(filew90_win(2)),ch10,'are mandatory secondary input',ch10,&
1154 [ + - ]: 1 : ' - ',trim(filew90_wout(1)),&
1155 [ + - ]: 1 : ' and ',trim(filew90_wout(2)),ch10,' are the output for the library',ch10,&
1156 [ + - ]: 1 : ' - ',trim(filew90_ramn(1)),&
1157 [ + - ]: 1 : ' and ',trim(filew90_ramn(2)),ch10,' contain random projections',ch10,&
1158 [ + - ]: 1 : ' - ',trim(filew90_amn(1)),&
1159 [ + - ]: 1 : ' and ',trim(filew90_amn(2)),ch10,' contain projections',ch10,&
1160 [ + - ]: 1 : ' - ',trim(filew90_mmn(1)),&
1161 [ + - ]: 1 : ' and ',trim(filew90_mmn(2)),ch10,' contain the overlap',ch10,&
1162 [ + - ]: 1 : ' - ',trim(filew90_eig(1)),&
1163 [ + - ]: 2 : ' and ',trim(filew90_eig(2)),ch10,' contain the eigenvalues'
1164 : : end if
1165 : 19 : call wrtout(units, msg)
1166 : :
1167 : 19 : write(msg, '(a,a)' ) ch10,'---------------------------------------------------------------'
1168 : 19 : call wrtout(units, msg)
1169 : :
1170 : 19 : end subroutine mlwfovlp_seedname
1171 : : !!***
1172 : :
1173 : : !!****f* m_mlwfovlp/mlwfovlp_setup
1174 : : !! NAME
1175 : : !! mlwfovlp_setup
1176 : : !!
1177 : : !! FUNCTION
1178 : : !! Routine which creates table g1 and ovikp necessary to compute
1179 : : !! overlap for Wannier code (www.wannier.org f90 version).
1180 : : !!
1181 : : !! INPUTS
1182 : : !! atom_symbols(natom)= table of symbol for each atom
1183 : : !! and each |p_lmn> non-local projector
1184 : : !! dtset <type(dataset_type)>=all input variables for this dataset
1185 : : !! filew90_win(nsppol) secondary input files for w90
1186 : : !! lwanniersetup= flag: only 1 is fully working.
1187 : : !! natom =number of atoms in cell.
1188 : : !! mband=maximum number of bands
1189 : : !! natom=number of atoms in cell.
1190 : : !! nkpt=number of k points.
1191 : : !! num_bands(isppol)=number of bands actually used to construct the wannier function
1192 : : !! nwan(isppol)= number of wannier fonctions (read in wannier90.win).
1193 : : !! dtset <type(dataset_type)>=all input variables for this dataset
1194 : : !! real_lattice(3,3)=dimensional primitive translations for real space
1195 : : !! in format required by wannier90
1196 : : !! recip_lattice(3,3)=dimensional primitive translations for reciprocal space
1197 : : !! in format required by wannier90
1198 : : !! rprimd(3,3)=dimensional primitive translations for real space (bohr)
1199 : : !! seed_name=character string for generating wannier90 filenames
1200 : : !! xcart(3,natom)=atomic coordinates in bohr
1201 : : !! xred(3,natom)=reduced dimensionless atomic coordinates
1202 : : !!
1203 : : !! OUTPUT
1204 : : !! band_in(mband,nsppol) = band to take into account for wannier calculation
1205 : : !! g1(3,nkpt,nntot) = G vector shift which is necessary to obtain k1+b
1206 : : !! from k2 in the case where k1+b does not belong to the 1st BZ.
1207 : : !! nband_inc(nsppol) = # of included bands
1208 : : !! nntot = number of k-point neighbour
1209 : : !! ovikp(nkpt,nntot)= gives nntot value of k2 (in the BZ) for each k1 (k2=k1+b mod(G))
1210 : : !!
1211 : : !! SIDE EFFECTS
1212 : : !! (only writing, printing)
1213 : : !!
1214 : : !! SOURCE
1215 : :
1216 : 19 : subroutine mlwfovlp_setup(atom_symbols,band_in,dtset,filew90_win,gamma_only,&
1217 : 19 : & g1,lwanniersetup,mband,natom,nband_inc,nkpt,&
1218 : 19 : & nntot,num_bands,num_nnmax,nsppol,nwan,ovikp,&
1219 : 19 : & proj_l,proj_m,proj_radial,proj_site,proj_s_loc, &
1220 : 19 : & proj_s_qaxis_loc,proj_x,proj_z,proj_zona,&
1221 : 19 : & real_lattice,recip_lattice,rprimd,seed_name,spinors,xcart,xred,exclude_bands)
1222 : :
1223 : : !Arguments---------------------------
1224 : : !scalars
1225 : : integer,intent(in) :: lwanniersetup,mband,natom,nkpt,nsppol
1226 : : integer,intent(in) :: num_nnmax
1227 : : integer,intent(out) :: nband_inc(nsppol),nntot,num_bands(nsppol),nwan(nsppol)
1228 : : logical,intent(in) :: gamma_only,spinors
1229 : : type(dataset_type),intent(in) :: dtset
1230 : : !arrays
1231 : : integer,intent(out) :: g1(3,nkpt,num_nnmax),ovikp(nkpt,num_nnmax)
1232 : : integer,intent(out) :: proj_l(mband,nsppol),proj_m(mband,nsppol),proj_radial(mband,nsppol)
1233 : : real(dp),intent(in) :: real_lattice(3,3)
1234 : : real(dp),intent(in) :: recip_lattice(3,3),rprimd(3,3),xred(3,natom)
1235 : : real(dp),intent(out) :: proj_site(3,mband,nsppol),proj_x(3,mband,nsppol),proj_z(3,mband,nsppol)
1236 : : real(dp),intent(out) :: proj_zona(mband,nsppol),xcart(3,natom)
1237 : : logical,intent(out) :: band_in(mband,nsppol)
1238 : : integer,intent(out) :: exclude_bands(mband,nsppol)
1239 : : character(len=3),intent(out) :: atom_symbols(natom)
1240 : : character(len=fnlen),intent(in) :: seed_name(nsppol),filew90_win(nsppol)
1241 : : integer, optional, intent(out) :: proj_s_loc(mband)
1242 : : real(dp), optional, intent(out) :: proj_s_qaxis_loc(3,mband)
1243 : :
1244 : : !Local variables---------------------------
1245 : : !scalars
1246 : : integer :: iatom,icb,ikpt,ikpt1,intot,isppol,itypat,jj,mband_,unt
1247 : : real(dp) :: znucl1
1248 : : character(len=2) :: symbol
1249 : : character(len=500) :: msg
1250 : : character(len=fnlen) :: filew90_nnkp
1251 : : type(atomdata_t) :: atom
1252 : : !arrays
1253 : : integer :: ngkpt(3)
1254 : : ! *************************************************************************
1255 : :
1256 : : !^^^^^^^^^^^^^^^^read wannier90.nnkp^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1257 [ - + ]: 19 : if (lwanniersetup==0) then !this part is not coded for nsppol>1
1258 : 0 : isppol=1
1259 [ # # # # ]: 0 : filew90_nnkp=trim(seed_name(isppol))//'.nnkp'
1260 [ # # ]: 0 : if (open_file(filew90_nnkp,msg,newunit=unt,form='formatted',status='old') /= 0) then
1261 : 0 : ABI_ERROR(msg)
1262 : : end if
1263 : 0 : read(unt,*)
1264 : 0 : read(unt,*) nntot , mband_, nwan(1)
1265 : 0 : write(msg, '(2a,2(i0,1x))')ch10,' mlwfovlp_setup nntot, mband, nwan ', nntot,mband_,nwan(1)
1266 : 0 : call wrtout(std_out,msg)
1267 [ # # ]: 0 : if (mband_ /= mband) then
1268 : 0 : write(msg, '(4a)' )'mband_ is not equal to mband ',ch10,'Action: check ',trim(filew90_nnkp)
1269 : 0 : ABI_ERROR(msg)
1270 : : end if
1271 [ # # ]: 0 : if(nwan(1) > mband) then
1272 : 0 : write(msg, '(4a)' )'nwan > mband ',ch10,'Action: check ',trim(filew90_nnkp)
1273 : 0 : ABI_ERROR(msg)
1274 : : end if
1275 [ # # ]: 0 : if(nwan(1) == 0) then
1276 : 0 : write(msg, '(4a)' )'nwan = 0 ',ch10, 'Action: check ',trim(filew90_nnkp)
1277 : 0 : ABI_ERROR(msg)
1278 : : end if
1279 [ # # ]: 0 : do ikpt=1,nkpt
1280 [ # # ]: 0 : do intot=1,nntot
1281 : : ! ikpt1: k point (ikpt=ikpt1)
1282 : : ! ovikp(intot,ikpt): neighbour number intot for ikpt
1283 : : ! g1(1:3,intot,ikpt): non reciprocal space vector between the 2 k-points
1284 : 0 : read(unt,*) ikpt1,ovikp(ikpt,intot),(g1(jj,ikpt,intot),jj=1,3)
1285 [ # # ]: 0 : if(ikpt1 /= ikpt) then
1286 : 0 : ABI_WARNING("ikpt1 .ne ikpt : ?")
1287 : : end if
1288 : : end do
1289 : : end do
1290 : 0 : close(unt)
1291 : 0 : write(msg, '(3a)' )ch10,trim(filew90_nnkp),'wannier90.nnkp has been read !'
1292 : 0 : call wrtout(std_out,msg)
1293 : :
1294 : 0 : ABI_ERROR(' exclude bands is not given in this case (not implemented) ')
1295 : :
1296 : : ! ^^^^^^^^^^^^^^^^^^^^^^^ call wannier_setup begin^^^^^^^^^^^^^^^^^^^^^^^^
1297 [ + - ]: 19 : else if (lwanniersetup==1) then
1298 [ + + ]: 39 : num_bands(:)=mband
1299 : : ! num_nnmax=12 !limit fixed for compact structure in wannier_setup.
1300 [ + + + + ]: 7927 : ovikp=0.d0
1301 : : ! "When nshiftk=1, kptrlatt is initialized as a diagonal (3x3) matrix, whose diagonal
1302 : : ! elements are the three values ngkpt(1:3)"
1303 : 19 : ngkpt(1)=dtset%kptrlatt(1,1)
1304 : 19 : ngkpt(2)=dtset%kptrlatt(2,2) ! have to verify that kptrlatt is diagonal
1305 : 19 : ngkpt(3)=dtset%kptrlatt(3,3)
1306 [ - + ]: 19 : ABI_CHECK(isdiagmat(dtset%kptrlatt), "kptrlatt must be diagonal please use ngkpt and nshiftk 1.")
1307 [ + + ]: 54 : do iatom=1,natom
1308 : 35 : itypat=dtset%typat(iatom)
1309 : 35 : znucl1=dtset%znucl(itypat)
1310 : 35 : call atomdata_from_znucl(atom, znucl1)
1311 : 35 : symbol=trim(adjustl(atom%symbol))
1312 : : !write(309,*) symbol
1313 : 35 : atom_symbols(iatom)=symbol
1314 [ + + ]: 194 : xcart(:,iatom)=rprimd(:,1)*xred(1,iatom)+ rprimd(:,2)*xred(2,iatom)+ rprimd(:,3)*xred(3,iatom)
1315 : : end do ! iatom
1316 : : ! write(std_out,*) xcart; write(std_out,*) Bohr_Ang; write(std_out,*) rprimd*Bohr_Ang
1317 : : ! write(std_out,*) seed_name; write(std_out,*) ngkpt; write(std_out,*) nkpt
1318 : : ! write(std_out,*) mband; write(std_out,*) natom; write(std_out,*) atom_symbols
1319 : 19 : write(msg, '(a,a)' )ch10,' mlwfovlp_setup: calling wannier90 library subroutine wannier_setup'
1320 : 19 : call wrtout(std_out,msg)
1321 : :
1322 : : #if defined HAVE_WANNIER90
1323 [ + + ]: 39 : nwan(:)=0
1324 [ + + ]: 39 : num_bands(:)=0
1325 : :
1326 [ + + ]: 39 : do isppol=1,nsppol
1327 : : #ifdef HAVE_WANNIER90_V1
1328 : : call wannier_setup(seed_name(isppol),ngkpt,nkpt& !input
1329 : : & ,real_lattice,recip_lattice,dtset%kptns& !input
1330 : : & ,mband,natom,atom_symbols,xcart*Bohr_Ang& !input
1331 : : & ,gamma_only,spinors& !input
1332 : : & ,nntot,ovikp,g1,num_bands(isppol),nwan(isppol)& !output
1333 : : & ,proj_site(:,:,isppol),proj_l(:,isppol)& !output
1334 : : & ,proj_m(:,isppol),proj_radial(:,isppol)& !output
1335 : : & ,proj_z(:,:,isppol),proj_x(:,:,isppol)& !output
1336 : : & ,proj_zona(:,isppol),exclude_bands(:,isppol)) !output
1337 : : #else
1338 : : !WANNIER90_V2 has the 2 optional arguments
1339 [ + - ]: 39 : if (present(proj_s_loc)) then
1340 : : call wannier_setup(seed_name(isppol),ngkpt,nkpt& !input
1341 : : & ,real_lattice,recip_lattice,dtset%kptns& !input
1342 : : & ,mband,natom,atom_symbols,xcart*Bohr_Ang& !input
1343 : : & ,gamma_only,spinors& !input
1344 : : & ,nntot,ovikp,g1,num_bands(isppol),nwan(isppol)& !output
1345 : : & ,proj_site(:,:,isppol),proj_l(:,isppol)& !output
1346 : : & ,proj_m(:,isppol),proj_radial(:,isppol)& !output
1347 : : & ,proj_z(:,:,isppol),proj_x(:,:,isppol)& !output
1348 : : & ,proj_zona(:,isppol),exclude_bands(:,isppol)& !output
1349 [ + - + + : 164 : & ,proj_s_loc,proj_s_qaxis_loc) !output
+ + ]
1350 : : else
1351 : : !no proj_s_loc provided
1352 : : call wannier_setup(seed_name(isppol),ngkpt,nkpt& !input
1353 : : & ,real_lattice,recip_lattice,dtset%kptns& !input
1354 : : & ,mband,natom,atom_symbols,xcart*Bohr_Ang& !input
1355 : : & ,gamma_only,spinors& !input
1356 : : & ,nntot,ovikp,g1,num_bands(isppol),nwan(isppol)& !output
1357 : : & ,proj_site(:,:,isppol),proj_l(:,isppol)& !output
1358 : : & ,proj_m(:,isppol),proj_radial(:,isppol)& !output
1359 : : & ,proj_z(:,:,isppol),proj_x(:,:,isppol)& !output
1360 [ # # # # : 0 : & ,proj_zona(:,isppol),exclude_bands(:,isppol)) !output
# # ]
1361 : : end if
1362 : : #endif
1363 : : end do !isppol
1364 : : ! if we do not have w90, avoid complaints about unused input variables
1365 : : #else
1366 : : ABI_UNUSED(gamma_only)
1367 : : ABI_UNUSED(real_lattice)
1368 : : ABI_UNUSED(recip_lattice)
1369 : : ABI_UNUSED(spinors)
1370 : : #endif
1371 : :
1372 [ + + ]: 39 : do isppol=1,nsppol
1373 : 20 : write(std_out,*) "1", nntot,nwan(isppol)
1374 : 20 : write(std_out,*) "2", num_bands(isppol) ! states on which wannier functions are computed
1375 : 20 : write(std_out,*) "3", proj_site(:,1:nwan(isppol),isppol)
1376 : 20 : write(std_out,*) "4", proj_l(1:nwan(isppol),isppol)
1377 : 20 : write(std_out,*) "5", proj_m(1:nwan(isppol),isppol)
1378 : 20 : write(std_out,*) "6", proj_radial(1:nwan(isppol),isppol)
1379 : 20 : write(std_out,*) "7", proj_z(:,1:nwan(isppol),isppol)
1380 : 20 : write(std_out,*) "8", proj_x(:,1:nwan(isppol),isppol)
1381 : 20 : write(std_out,*) "9", proj_zona(1:nwan(isppol),isppol)
1382 : 39 : write(std_out,*) "10", exclude_bands(:,isppol)
1383 : : end do!isppol
1384 : : end if ! lwanniersetup
1385 : :
1386 [ + + ]: 39 : do isppol=1,nsppol
1387 [ + + ]: 214 : band_in(:,isppol)=.true.
1388 [ + + ]: 214 : do icb=1,mband
1389 [ + + ]: 214 : if(exclude_bands(icb,isppol) /= 0) band_in(exclude_bands(icb,isppol),isppol)=.false.
1390 : : end do
1391 : 20 : nband_inc(isppol)=0
1392 [ + + ]: 233 : do icb=1, mband
1393 [ + + ]: 214 : if (band_in(icb,isppol)) nband_inc(isppol) = nband_inc(isppol)+1
1394 : : end do
1395 : : end do !isppol
1396 : :
1397 [ + + + + : 29 : if (any(mband.gt.num_bands(:))) then
+ + ]
1398 : 10 : write(msg, '(a,a)' )ch10,' The following bands are excluded from the calculation of wannier functions:'
1399 : 10 : call wrtout(std_out,msg)
1400 : :
1401 [ + + ]: 20 : do isppol=1,nsppol
1402 [ - + ]: 10 : if(nsppol==2) then
1403 : 0 : write(msg,'("For spin",i2)')isppol
1404 : 0 : call wrtout(std_out,msg)
1405 : : end if !nsppol
1406 [ - + + + ]: 32 : do jj=1,mband-num_bands(isppol),10
1407 : 12 : write(msg,'(10i7)') exclude_bands(jj:min(jj+9,mband-num_bands(isppol)),isppol)
1408 : 22 : call wrtout(std_out,msg)
1409 : : end do
1410 : : end do !isppol
1411 : : end if
1412 : :
1413 [ + + ]: 39 : do isppol=1,nsppol
1414 [ + + ]: 20 : if(nsppol==2) then
1415 : 2 : write(msg,'("For spin",i2)')isppol
1416 : 2 : call wrtout(std_out,msg)
1417 : : end if !nsppol
1418 [ + - ]: 20 : write(msg, '(a,i0,3a)' )ch10,nwan(isppol),' wannier functions will be computed (see ',trim(filew90_win(isppol)),')'
1419 : 20 : call wrtout(std_out,msg)
1420 : : ! write(std_out,*) exclude_bands(icb),band_in(icb)
1421 : 20 : write(msg, '(a,i0,a)' )ch10,num_bands(isppol),' bands will be used to extract wannier functions'
1422 : 20 : call wrtout(std_out,msg)
1423 [ - + ]: 20 : if (num_bands(isppol).lt.nwan(isppol)) then
1424 : : write(msg, '(4a)' )&
1425 : 0 : ' number of bands is lower than the number of wannier functions',ch10,&
1426 [ # # ]: 0 : ' Action : check input file and ',trim(filew90_win(isppol))
1427 : 0 : ABI_ERROR(msg)
1428 [ + + ]: 20 : else if (num_bands(isppol)==nwan(isppol)) then
1429 : 15 : write(msg, '(4a)' )ch10,&
1430 : 15 : ' Number of bands is equal to the number of wannier functions',ch10,&
1431 : 30 : ' Disentanglement is not necessary'
1432 : 15 : call wrtout(std_out,msg)
1433 : : else if (num_bands(isppol).gt.nwan(isppol)) then
1434 : 5 : write(msg, '(4a)' )ch10,&
1435 : 5 : ' Number of bands is larger than the number of wannier functions',ch10,&
1436 : 10 : ' Disentanglement will be necessary'
1437 : 5 : call wrtout(std_out,msg)
1438 : : end if
1439 : 20 : write(msg, '(2x,a,a,i0,1x,a)' )ch10,' Each k-point has: ', nntot,' neighbours'
1440 : 39 : call wrtout(std_out,msg)
1441 : : end do !isppol
1442 : :
1443 : 19 : end subroutine mlwfovlp_setup
1444 : : !!***
1445 : :
1446 : : !!****f* m_mlwfovlp/mlwfovlp_pw
1447 : : !! NAME
1448 : : !! mlwfovlp_pw
1449 : : !!
1450 : : !! FUNCTION
1451 : : !! Routine which computes PW part of overlap M_{mn}(k,b)
1452 : : !! for Wannier code (www.wannier.org f90 version).
1453 : : !!
1454 : : !! INPUTS
1455 : : !! cg(2,mpw*nspinor*mband*mkmem*nsppol)=planewave coefficients of wavefunctions.
1456 : : !! g1(3,nkpt,nntot) = G vector shift which is necessary to obtain k1+b
1457 : : !! iwav(mband,nkpt,nsppol): shift for pw components in cg.
1458 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates.
1459 : : !! mband=maximum number of bands
1460 : : !! mgfft=maximum size of 1D FFTs
1461 : : !! mkmem =number of k points treated by this node.
1462 : : !! mpi_enreg=information about MPI parallelization
1463 : : !! mpw=maximum dimensioned size of npw.
1464 : : !! nfft=(effective) number of FFT grid points (for this processor) (see NOTES at beginning of scfcv)
1465 : : !! ngfft(18)=contain all needed information about 3D FFT (see NOTES at beginning of scfcv)
1466 : : !! nkpt=number of k points.
1467 : : !! npwarr(nkpt)=number of planewaves in basis at this k point
1468 : : !! nspinor=number of spinorial components of the wavefunctions
1469 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
1470 : : !! ovikp(nkpt,nntot)= gives nntot value of k2 (in the BZ) for each k1 (k2=k1+b mod(G))
1471 : : !! seed_name= seed_name of files containing cg for all k-points to be used with MPI
1472 : : !!
1473 : : !! OUTPUT
1474 : : !! cm1(2,mband,mband,nntot,nkpt,nsppol): overlap <u_(nk1)|u_(mk1+b)>.
1475 : : !!
1476 : : !! SIDE EFFECTS
1477 : : !! (only writing, printing)
1478 : : !!
1479 : : !! SOURCE
1480 : :
1481 : 19 : subroutine mlwfovlp_pw(mywfc,cm1,g1,kg,mband,mkmem,mpi_enreg,mpw,nfft,ngfft,nkpt,nntot,&
1482 : 19 : npwarr,nspinor,nsppol,ovikp)
1483 : :
1484 : : !Arguments ------------------------------------
1485 : : !scalars
1486 : : integer,intent(in) :: mband,mkmem,mpw,nfft,nkpt,nntot
1487 : : integer,intent(in) :: nspinor,nsppol
1488 : : ! character(len=fnlen) :: seed_name !seed names of files containing cg info used in case of MPI
1489 : : class(abstract_wf) :: mywfc
1490 : : type(MPI_type),intent(in) :: mpi_enreg
1491 : : !arrays
1492 : : integer,intent(in) :: g1(3,nkpt,nntot),kg(3,mpw*mkmem),ngfft(18),npwarr(nkpt)
1493 : : ! integer,intent(in) :: iwav(mband,nkpt,nsppol)
1494 : : integer,intent(in) :: ovikp(nkpt,nntot)
1495 : : ! real(dp),intent(in) :: cg(2,mpw*nspinor*mband*mkmem*nsppol)
1496 : : real(dp),intent(out) :: cm1(2,mband,mband,nntot,nkpt,nsppol)
1497 : :
1498 : : !Local variables-------------------------------
1499 : : !scalars
1500 : : integer :: iband1,iband2,ierr,ig,ig1,ig1b,ig2,ig2b
1501 : : integer :: ig3,ig3b,igk1,igk2,ikg,ikpt,ikpt1,ikpt2,imntot,index,intot
1502 : : integer :: ispinor,isppol,me,n1,n2,n3,npoint,npoint2,npw_k,npw_k2
1503 : : integer :: nprocs,comm
1504 : 19 : integer,allocatable :: indpwk(:,:),kg_k(:,:), invpwk(:,:)
1505 : : character(len=500) :: msg
1506 : : logical:: lfile
1507 : 19 : real(dp),allocatable :: cg_read(:,:) !to be used in case of MPI
1508 : : !************************************************************************
1509 : :
1510 : 19 : write(msg, '(a,a)' ) ch10, '** mlwfovlp_pw : compute pw part of overlap'
1511 : 19 : call wrtout(std_out, msg)
1512 : :
1513 : : !initialize flags
1514 : 19 : lfile=.false.
1515 : : !mpi initialization
1516 : 19 : comm=MPI_enreg%comm_cell
1517 : 19 : nprocs=xmpi_comm_size(comm)
1518 : 19 : me=MPI_enreg%me_kpt
1519 : :
1520 [ - + ]: 19 : if(nprocs>1) then
1521 [ # # # # : 0 : ABI_MALLOC(cg_read,(2,nspinor*mpw*mband))
# # # # #
# # # ]
1522 : : end if
1523 : :
1524 : :
1525 : : !****************compute intermediate quantities (index, shifts) ******
1526 : : !------------compute index for g points--------------------------------
1527 : : !ig is a plane waves which belongs to the sphere ecut for ikpt (they
1528 : : !are npwarr(ikpt))
1529 : : !npoint is the position in the grid of planes waves
1530 : : !(they are nfft)
1531 : : !indpwk is a application ig-> npoint
1532 : : !invpwk is not an application (some npoint have no ig corresponding)
1533 : : !cg are ordered with npw_k !
1534 : : !----------------------------------------------------------------------
1535 : : !------------compute index for g points--------------------------------
1536 : : !----------------------------------------------------------------------
1537 : 19 : write(msg, '(a,a)' ) ch10,' first compute index for g-points'
1538 : 19 : call wrtout(std_out, msg)
1539 : :
1540 : : ! Allocations
1541 [ - + + - : 57 : ABI_MALLOC(kg_k,(3,mpw))
+ - + - -
+ - + ]
1542 [ - + + - : 76 : ABI_MALLOC(indpwk,(nkpt,mpw))
- + + - +
- + - - +
- + ]
1543 [ - + + - : 76 : ABI_MALLOC(invpwk,(nkpt,nfft))
- + + - +
- + - - +
- + ]
1544 : :
1545 : 19 : n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
1546 [ + + + + ]: 7395000 : invpwk=0
1547 [ + + + + ]: 205756 : indpwk=0
1548 [ + + + + ]: 54231 : kg_k=0
1549 : :
1550 [ + + ]: 38 : do isppol=1,1 !invpwk is not spin dependent so we just do it once
1551 : 19 : ikg=0
1552 [ + + ]: 678 : do ikpt=1,nkpt
1553 : : ! MPI:cycle over k-points not treated by this node
1554 [ - + ]: 640 : if (nprocs>1 ) then !sometimes we can have just one processor
1555 : : !print *, "MPI_enreg%proc_distrb(ikpt,1,isppol)", ikpt, isppol , MPI_enreg%proc_distrb(ikpt,1,isppol)
1556 [ # # ]: 0 : if (ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-MPI_enreg%me) /= 0) CYCLE
1557 : : end if
1558 : :
1559 : : ! write(std_out,*)'me',me,'ikpt',ikpt,'isppol',isppol
1560 [ + + ]: 6992088 : do npoint=1,nfft
1561 [ - + ]: 6992088 : if(invpwk(ikpt,npoint)/=0 )then
1562 : 0 : write(std_out,*) "error0 , invpwk is overwritten"
1563 : 0 : write(std_out,*) ikpt,npoint
1564 : 0 : ABI_ERROR("Aborting now")
1565 : : end if
1566 : : end do
1567 : 640 : npw_k=npwarr(ikpt)
1568 : : ! write(std_out,*) ikpt,npw_k,nfft
1569 [ + + + + ]: 741452 : kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
1570 [ + + ]: 185843 : do ig=1,npw_k
1571 [ - + ]: 185203 : if(ig.gt.mpw) then
1572 : 0 : write(std_out,*)"error ig",ig,"greater than mpw ",mpw
1573 : 0 : ABI_ERROR("Aborting now")
1574 : : end if
1575 [ - + ]: 185203 : if(indpwk(ikpt,ig)/=0) then
1576 : 0 : write(std_out,*) "error, indpwk is overwritten"
1577 : 0 : write(std_out,*) ikpt,ig,indpwk(ikpt,ig)
1578 : 0 : ABI_ERROR("Aborting now")
1579 : : end if
1580 : 185203 : ig1=modulo(kg_k(1,ig),n1)
1581 : 185203 : ig2=modulo(kg_k(2,ig),n2)
1582 : 185203 : ig3=modulo(kg_k(3,ig),n3)
1583 : 185203 : indpwk(ikpt,ig)=ig1+1+n1*(ig2+n2*ig3)
1584 : 185203 : npoint=indpwk(ikpt,ig)
1585 [ - + ]: 185203 : if(npoint.gt.nfft) then
1586 : 0 : ABI_ERROR("error npoint")
1587 : : end if
1588 : : ! write(std_out,*) ikpt,ig,npoint,invpwk(ikpt,npoint)
1589 [ - + ]: 185203 : if(invpwk(ikpt,npoint)/=0) then
1590 : 0 : write(std_out,*) "error, invpwk is overwritten"
1591 : 0 : write(std_out,*) ikpt,ig,npoint,invpwk(ikpt,npoint)
1592 : 0 : ABI_ERROR("Aborting now")
1593 : : end if
1594 : 185843 : invpwk(ikpt,npoint)=ig
1595 : : ! write(std_out,*)'ikpt,npoint,invpwk',ikpt,npoint,invpwk(ikpt,npoint)
1596 : : ! if(ikpt.eq.1) write(std_out,*) "ig npoint",ig, npoint
1597 : : ! write(std_out,*) "ikpt ig npoint",ikpt,ig, npoint
1598 : : end do
1599 : 19 : ikg=ikg+npw_k
1600 : :
1601 : : end do !ikpt
1602 : : end do !isppol
1603 : : !write(std_out,*) "index for g points has been computed"
1604 : :
1605 : 19 : call xmpi_sum(invpwk,comm,ierr)
1606 : :
1607 : : !----------------------------------------------------------------------
1608 : : !------------test invpwk-----------------------------------------------
1609 : : !----------------------------------------------------------------------
1610 : : !write(std_out,*) "TEST INVPWK"
1611 : : !ikpt=3
1612 : : !isppol=1
1613 : : !do ig=1,npwarr(ikpt)
1614 : : !npoint=indpwk(ikpt,ig)
1615 : : !write(std_out,*) "ig npoint ",ig, npoint
1616 : : !write(std_out,*) "ig npoint inv",invpwk(ikpt,npoint),npoint
1617 : : !end do
1618 : : !do ig3=1,n3
1619 : : !do ig2=1,n2
1620 : : !do ig1=1,n1
1621 : : !npoint=ig1+(ig2-1)*n1+(ig3-1)*n2*n1
1622 : : !ig=invpwk(ikpt,npoint)
1623 : : !! if(ig/=0) write(std_out,*) "ig npoint",ig, npoint
1624 : : !end do
1625 : : !end do
1626 : : !end do
1627 : :
1628 [ - + ]: 19 : ABI_FREE(kg_k)
1629 [ - + ]: 19 : ABI_FREE(indpwk)
1630 : :
1631 : : !***********************************************************************
1632 : : !**calculate overlap M_{mn}(k,b)=<\Psi_{k,m}|e^{-ibr}|\Psi_{k+b,n}>*****
1633 : : !***********************************************************************
1634 : 19 : write(msg, '(a,a)' ) ch10,' mlwfovlp_pw : compute overlaps '
1635 : 19 : call wrtout(std_out, msg)
1636 : 19 : write(msg, '(a,a)' ) ch10," nkpt nntot mband "
1637 : 19 : call wrtout(std_out, msg)
1638 : 19 : write(msg, '(i6,2x,i6,2x,i6,2x,i6)' ) nkpt,nntot,mband
1639 : 19 : call wrtout(std_out, msg)
1640 [ + + + + : 3614231 : cm1=zero
+ + + + +
+ + + ]
1641 : 19 : write(msg, '(a)' ) ' '
1642 : 19 : call wrtout(std_out, msg)
1643 : :
1644 [ + + ]: 39 : do isppol=1,nsppol
1645 : 20 : imntot=0
1646 [ + + ]: 743 : do ikpt1=1,nkpt
1647 : : ! MPI:cycle over k-points not treated by this node
1648 [ - + ]: 704 : if (nprocs>1) then
1649 [ # # ]: 0 : if (ABS(MPI_enreg%proc_distrb(ikpt1,1,isppol)-me) /= 0) CYCLE
1650 : : end if
1651 : 704 : write(msg, '(a,i0,a,i0,a,i0)' ) ' Processor: ',me,' computes k-point: ',ikpt1,', and spin: ',isppol
1652 : 704 : call wrtout(std_out, msg)
1653 : :
1654 [ + + ]: 7108 : do intot=1,nntot
1655 : 6384 : lfile=.false. !flag to know if this kpt will be read from a file, see below
1656 : 6384 : imntot=imntot+1
1657 : 6384 : ikpt2= ovikp(ikpt1,intot)
1658 : : ! write(std_out,*)'me',me,'ikpt1',ikpt1,'ikpt2',ikpt2,'intot',intot,'isppol',isppol
1659 : :
1660 : : !
1661 : : ! MPI: if ikpt2 not found in this processor then
1662 : : ! read info from an unformatted file
1663 : : ! TODO: also get MPI mapping to retrieve who has this wf k-point
1664 : : !
1665 : : ! if (nprocs>1) then
1666 : : ! if ( ABS(MPI_enreg%proc_distrb(ikpt2,1,isppol)-me) /=0) then
1667 : : ! lfile=.true.
1668 : : ! write(cg_file,'(a,I5.5,".",I1)') trim(seed_name),ikpt2,isppol
1669 : : ! iunit=1000+ikpt2+ikpt2*(isppol-1)
1670 : : ! npw_k2=npwarr(ikpt2)
1671 : : ! open (unit=iunit, file=cg_file,form='unformatted',status='old',iostat=ios)
1672 : : ! if(ios /= 0) then
1673 : : ! write(msg,*) " mlwfovlp_pw: file",trim(cg_file), "not found"
1674 : : ! ABI_ERROR(msg)
1675 : : ! end if
1676 : : ! !
1677 : : ! do iband2=1,mband
1678 : : ! do ipw=1,npw_k2*nspinor
1679 : : ! index=ipw+(iband2-1)*npw_k2*nspinor
1680 : : ! read(iunit) (cg_read(ii,index),ii=1,2)
1681 : : ! ! if(me==0 .and. ikpt2==4)write(300,*)'ipw,iband2,index',ipw,iband2,index,cg_read(:,index)
1682 : : ! ! if(me==1 .and. ikpt2==4)write(301,*)'ipw,iband2,index',ipw,iband2,index,cg_read(:,index)
1683 : : ! end do
1684 : : ! end do
1685 : : ! close(iunit)
1686 : : ! end if
1687 : : ! end if
1688 : :
1689 [ - + ]: 6384 : if(nprocs>1) then
1690 : : !call mywfc%read_cg(cg_read, ikpt2)
1691 : : !call mywfc%read_cg( ikpt2, isppol, cg_read)
1692 : :
1693 [ # # ]: 0 : if (ABS(MPI_enreg%proc_distrb(ikpt2,1,isppol)-me) /= 0) then
1694 : 0 : lfile=.true.
1695 : 0 : call mywfc%load_cg(ikpt2, isppol, cg_read)
1696 : : endif
1697 : : end if
1698 : :
1699 : 6384 : npw_k=npwarr(ikpt1)
1700 : 6384 : npw_k2=npwarr(ikpt2)
1701 [ + + ]: 133872 : do ig3=1,n3
1702 [ + + ]: 2849904 : do ig2=1,n2
1703 [ + + ]: 66270784 : do ig1=1,n1
1704 : : ! write(std_out,*) isppol,ikpt1,iband1,iband2,intot
1705 : 63427264 : npoint=ig1+(ig2-1)*n1+(ig3-1)*n2*n1
1706 [ - + ]: 63427264 : if(npoint.gt.nfft) then
1707 : 0 : ABI_ERROR("error npoin Aborting now")
1708 : : end if
1709 : 63427264 : ig1b=ig1+g1(1,ikpt1,intot)
1710 : 63427264 : ig2b=ig2+g1(2,ikpt1,intot)
1711 : 63427264 : ig3b=ig3+g1(3,ikpt1,intot)
1712 : : ! write(std_out,*) ig1,ig2,ig3; write(std_out,*) ig1b,ig2b,ig3b
1713 [ + + ]: 63427264 : if(ig1b.lt.1) ig1b=ig1b+n1
1714 [ + + ]: 63427264 : if(ig2b.lt.1) ig2b=ig2b+n2
1715 [ + + ]: 63427264 : if(ig3b.lt.1) ig3b=ig3b+n3
1716 [ + + ]: 63427264 : if(ig1b.gt.n1) ig1b=ig1b-n1
1717 [ + + ]: 63427264 : if(ig2b.gt.n2) ig2b=ig2b-n2
1718 [ + + ]: 63427264 : if(ig3b.gt.n3) ig3b=ig3b-n3
1719 : 63427264 : npoint2=ig1b+(ig2b-1)*n1+(ig3b-1)*n2*n1
1720 [ - + ]: 63427264 : if(npoint2.gt.nfft) then
1721 : 0 : ABI_ERROR("error npoint c")
1722 : : end if
1723 : 63427264 : igk1=invpwk(ikpt1,npoint)
1724 : 63427264 : igk2=invpwk(ikpt2,npoint2)
1725 : :
1726 : : ! if(intot==10) write(std_out,*)'Before igk1 and igk2',ikpt1,ikpt2,isppol
1727 : :
1728 [ + + ]: 66144000 : if(igk1/=0.and.igk2/=0) then
1729 [ + + ]: 17453252 : do iband2=1,mband
1730 [ + + ]: 216841732 : do iband1=1,mband
1731 [ + + ]: 468974288 : do ispinor=1,nspinor
1732 [ - + ]: 253737536 : if(lfile) index=ispinor + nspinor*(igk2-1) + nspinor*npw_k2*(iband2-1) !In case of MPI, see below
1733 : : ! TODO : Check if the index in the cg_elems are correct.
1734 : : !
1735 : : ! If MPI sometimes the info was read from an unformatted file
1736 : : ! If that is the case lfile==.true.
1737 : : !
1738 : : ! TODO: this filter should be outside, not inside 1000 loops!!!
1739 : 199388480 : if(lfile) then
1740 : : cm1(1,iband1,iband2,intot,ikpt1,isppol)=cm1(1,iband1,iband2,intot,ikpt1,isppol)+ &
1741 : : & mywfc%cg_elem(1, igk1, ispinor, iband1, ikpt1, isppol) *cg_read(1,index)&
1742 : 0 : & + mywfc%cg_elem(2, igk1, ispinor, iband1, ikpt1, isppol)*cg_read(2,index)
1743 : : cm1(2,iband1,iband2,intot,ikpt1,isppol)=cm1(2,iband1,iband2,intot,ikpt1,isppol)+ &
1744 : : & mywfc%cg_elem(1, igk1, ispinor, iband1, ikpt1, isppol)*cg_read(2,index)&
1745 : 0 : &- mywfc%cg_elem(2, igk1, ispinor, iband1, ikpt1, isppol)*cg_read(1,index)
1746 : : else
1747 : : ! TODO: Here it is very inefficient.
1748 : : ! Could be replaced with the fftbox and dotproduct.
1749 : : ! cgtk_rotate. sphere.
1750 : : !
1751 : : cm1(1,iband1,iband2,intot,ikpt1,isppol)=&
1752 : : & cm1(1,iband1,iband2,intot,ikpt1,isppol) &
1753 : : & + mywfc%cg_elem(1, igk1, ispinor,iband1, ikpt1, isppol) &
1754 : : & *mywfc%cg_elem(1, igk2, ispinor,iband2, ikpt2, isppol) &
1755 : : & +mywfc%cg_elem(2, igk1, ispinor,iband1, ikpt1, isppol) &
1756 : 253737536 : & *mywfc%cg_elem(2, igk2, ispinor,iband2, ikpt2, isppol)
1757 : : cm1(2,iband1,iband2,intot,ikpt1,isppol)= &
1758 : : & cm1(2,iband1,iband2,intot,ikpt1,isppol) &
1759 : : & + mywfc%cg_elem(1, igk1, ispinor,iband1, ikpt1, isppol) &
1760 : : & *mywfc%cg_elem( 2, igk2, ispinor,iband2, ikpt2, isppol) &
1761 : : & -mywfc%cg_elem( 2, igk1, ispinor,iband1, ikpt1, isppol) &
1762 : 253737536 : & *mywfc%cg_elem( 1, igk2, ispinor,iband2, ikpt2, isppol)
1763 : : end if
1764 : : end do !ispinor
1765 : : end do ! iband1
1766 : : end do ! iband2
1767 : : end if
1768 : : end do ! ig1
1769 : : end do ! ig2
1770 : : end do ! ig3
1771 : : end do ! intot
1772 : : end do ! ikpt1
1773 : : end do ! isppol
1774 : :
1775 [ - + ]: 19 : ABI_FREE(invpwk)
1776 [ - + ]: 19 : ABI_SFREE(cg_read)
1777 : :
1778 [ - + ]: 38 : end subroutine mlwfovlp_pw
1779 : : !!***
1780 : :
1781 : : !!****f* m_mlwfovlp/mlwfovlp_proj
1782 : : !! NAME
1783 : : !! mlwfovlp_proj
1784 : : !!
1785 : : !! FUNCTION
1786 : : !! Routine which computes projection A_{mn}(k) for Wannier code (www.wannier.org f90 version).
1787 : : !!
1788 : : !! INPUTS
1789 : : !! cg(2,mpw*nspinor*mband*mkmem*nsppol)=planewave coefficients of wavefunctions
1790 : : !! cprj(natom,nspinor*mband*mkmem*nsppol)= <p_lmn|Cnk> coefficients for each WF |Cnk>
1791 : : !! and each |p_lmn> non-local projector
1792 : : !! dtset <type(dataset_type)>=all input variables for this dataset
1793 : : !! filew90_win = secondary input file for wannier90 (WAS NOT USED IN v6.7.1 - so has been temporarily removed)
1794 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates.
1795 : : !! lproj= flag 0: no projections, 1: random projections,
1796 : : !! 2: projections on atomic orbitals
1797 : : !! 3: projections on projectors
1798 : : !! mband=maximum number of bands
1799 : : !! mkmem =number of k points treated by this node.
1800 : : !! npwarr(nkpt)=number of planewaves in basis at this k point
1801 : : !! mpi_enreg=information about MPI parallelization
1802 : : !! mpw=maximum dimensioned size of npw.
1803 : : !! natom=number of atoms in cell.
1804 : : !! nattyp(ntypat)= # atoms of each type.
1805 : : !! nkpt=number of k points.
1806 : : !! nspinor=number of spinorial components of the wavefunctions
1807 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
1808 : : !! ntypat=number of types of atoms in unit cell.
1809 : : !! num_bands=number of bands actually used to construct the wannier function
1810 : : !! nwan= number of wannier fonctions (read in wannier90.win).
1811 : : !! proj_l(mband)= angular part of the projection function (quantum number l)
1812 : : !! proj_m(mband)= angular part of the projection function (quantum number m)
1813 : : !! proj_radial(mband)= radial part of the projection.
1814 : : !! proj_site(3,mband)= site of the projection.
1815 : : !! proj_x(3,mband)= x axis for the projection.
1816 : : !! proj_z(3,mband)= z axis for the projection.
1817 : : !! proj_zona(mband)= extension of the radial part.
1818 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
1819 : : !!
1820 : : !! OUTPUT
1821 : : !! A_matrix(num_bands,nwan,nkpt,nsppol)= Matrix of projections needed by wannier_run
1822 : : !! ( also wannier90random.amn is written)
1823 : : !!
1824 : : !! SIDE EFFECTS
1825 : : !! (only writing, printing)
1826 : : !!
1827 : : !! SOURCE
1828 : :
1829 : 19 : subroutine mlwfovlp_proj(A_matrix,band_in,mywfc, dtset,gprimd,just_augmentation,kg,&
1830 : 19 : lproj,max_num_bands,mband,mkmem,mpi_enreg,mpw,mwan,natom,nattyp,&
1831 : 19 : nkpt,npwarr,nspinor,&
1832 : 38 : nsppol,ntypat,num_bands,nwan,pawtab,proj_l,proj_m,proj_radial,&
1833 [ - + ]: 19 : proj_site,proj_x,proj_z,proj_zona,psps,ucvol)
1834 : :
1835 : : !Arguments ------------------------------------
1836 : : !scalars
1837 : : complex(dp),parameter :: c1=(1._dp,0._dp)
1838 : : integer,intent(in) :: lproj,max_num_bands,mband,mkmem,mpw,mwan,natom,nkpt,nspinor,nsppol
1839 : : integer,intent(in) :: ntypat
1840 : : type(MPI_type),intent(in) :: mpi_enreg
1841 : : type(dataset_type),intent(in) :: dtset
1842 : : type(pseudopotential_type),intent(in) :: psps
1843 : : !arrays
1844 : : integer ::nattyp(ntypat)
1845 : : integer,intent(in) :: kg(3,mpw*mkmem),npwarr(nkpt),num_bands(nsppol),nwan(nsppol),proj_l(mband,nsppol)
1846 : : integer,intent(in) :: proj_m(mband,nsppol)
1847 : : integer,intent(inout)::proj_radial(mband,nsppol)
1848 : : !real(dp),intent(in) :: cg(2,mpw*nspinor*mband*mkmem*nsppol)
1849 : : real(dp),intent(in) :: gprimd(3,3),proj_site(3,mband,nsppol)
1850 : : real(dp),intent(in) :: proj_x(3,mband,nsppol),proj_z(3,mband,nsppol),proj_zona(mband,nsppol)
1851 : : complex(dp),intent(out) :: A_matrix(max_num_bands,mwan,nkpt,nsppol)
1852 : : !character(len=fnlen),intent(in) :: filew90_win(nsppol)
1853 : : logical,intent(in) :: band_in(mband,nsppol)
1854 : : logical,intent(in)::just_augmentation(mwan,nsppol)
1855 : : !type(pawcprj_type) :: cprj(natom,nspinor*mband*mkmem*nsppol)
1856 : : !type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
1857 : : type(pawtab_type),intent(in) :: pawtab(:)
1858 : : class(abstract_wf), intent(inout) :: mywfc
1859 : :
1860 : : !Local variables-------------------------------
1861 : : !scalars
1862 : : integer :: iatom,iatprjn,iband,iband1,iband2,ibg,icat,icg,icg_shift
1863 : : integer :: idum,ikg,ikpt,ilmn,ipw,iproj
1864 : : integer :: ispinor,isppol,itypat,iwan,jband,jj1,libprjn
1865 : : integer :: lmn_size,natprjn,nband_k,nbprjn,npw_k, sumtmp
1866 : : integer :: max_lmax,max_lmax2,mproj,nprocs,comm,rank, idx
1867 : : real(dp),parameter :: qtol=2.0d-8
1868 : : real(dp) :: arg,norm_error,norm_error_bar
1869 : : real(dp) :: ucvol,x1,x2,xnorm,xnormb,xx,yy,zz
1870 : 38 : complex(dp) :: amn_tmp(nspinor)
1871 : : complex(dp) :: cstr_fact
1872 : : character(len=500) :: msg
1873 : : !arrays
1874 : 38 : integer :: kg_k(3,mpw),lmax(nsppol),lmax2(nsppol),nproj(nsppol)
1875 : 19 : integer,allocatable :: lprjn(:),npprjn(:)
1876 : : real(dp) :: kpg(3),kpt(3)
1877 : 19 : real(dp),allocatable :: amn(:,:,:,:,:),amn2(:,:,:,:,:,:,:)
1878 : 19 : real(dp),allocatable :: gsum2(:),kpg2(:),radial(:)
1879 : 19 : complex(dp),allocatable :: gf(:,:),gft_lm(:), ylmc_fac(:,:,:),ylmcp(:)
1880 : : !Tables 3.1 & 3.2, User guide
1881 : : integer,parameter :: orb_l_defs(-5:3)=(/2,2,1,1,1,0,1,2,3/)
1882 : : ! integer,parameter :: mtransfo(0:3,7)=&
1883 : : !& reshape((/1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,-2,-1,2,1,0,0,0,-1,1,2,-2,-3,3/),(/4,7/))
1884 : : !************************************************************************
1885 : :
1886 : : !mpi initialization
1887 : 19 : comm=MPI_enreg%comm_cell
1888 : 19 : nprocs=xmpi_comm_size(comm)
1889 : 19 : rank=MPI_enreg%me_kpt
1890 : :
1891 : : ! Check input variables
1892 [ - + ]: 19 : if ((lproj/=1).and.(lproj/=2).and.(lproj/=5)) then
1893 : 0 : write(msg, '(3a)' )' Value of lproj no allowed ',ch10,' Action: change lproj.'
1894 : 0 : ABI_ERROR(msg)
1895 : : end if
1896 : :
1897 : 19 : write(msg, '(a,a)' )ch10,'** mlwfovlp_proj: compute A_matrix of initial guess for wannier functions'
1898 : 19 : call wrtout(std_out,msg)
1899 : :
1900 : : !Initialize to 0.d0
1901 [ + + + + : 65031 : A_matrix(:,:,:,:)=cmplx(0.d0,0.d0)
+ + + + ]
1902 : :
1903 : : !********************* Write Random projectors
1904 [ + + ]: 19 : if(lproj==1) then
1905 : 6 : idum=123456
1906 : : ! Compute random projections
1907 [ - + + - : 36 : ABI_MALLOC(amn,(2,mband,mwan,nkpt,nsppol))
- + + - -
+ + - - +
+ - + - +
- - + -
+ ]
1908 [ + + + + : 3324 : amn=zero
+ + + + +
+ ]
1909 [ + + ]: 12 : do isppol=1,nsppol
1910 [ + + ]: 60 : do ikpt=1,nkpt
1911 : : ! MPI: cycle over kpts not treated by this node
1912 [ + - ]: 48 : if (ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-rank)/=0) CYCLE
1913 : : ! write(std_out,'("kpt loop2: ikpt",i3," rank ",i3)') ikpt,rank
1914 : :
1915 [ + + ]: 310 : do iband1=1,mband
1916 : 256 : xnormb=0.d0
1917 [ + + ]: 1280 : do iband2=1,nwan(isppol)
1918 : 1024 : x1=uniformrandom(idum)
1919 : 1024 : x2=uniformrandom(idum)
1920 : 1024 : xnorm=sqrt(x1**2+x2**2)
1921 : 1024 : xnormb=xnormb+xnorm
1922 : 1024 : amn(1,iband1,iband2,ikpt,isppol)=x1
1923 : 1280 : amn(2,iband1,iband2,ikpt,isppol)=x2
1924 : : end do
1925 [ + + ]: 1328 : do iband2=1,nwan(isppol)
1926 : 1024 : amn(1,iband1,iband2,ikpt,isppol)=amn(1,iband1,iband2,ikpt,isppol)/xnormb
1927 : 1280 : amn(2,iband1,iband2,ikpt,isppol)=amn(2,iband1,iband2,ikpt,isppol)/xnormb
1928 : : end do !iband2
1929 : : end do !iband1
1930 : : end do !ikpt
1931 : : end do !isppol
1932 [ + + ]: 12 : do isppol=1,nsppol
1933 [ + + ]: 60 : do ikpt=1,nkpt
1934 : : ! MPI: cycle over kpts not treated by this node
1935 [ + - ]: 48 : if (ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-rank)/=0) CYCLE
1936 [ + + ]: 246 : do iband2=1,nwan(isppol)
1937 : : jband=0
1938 [ + + ]: 1264 : do iband1=1,mband
1939 [ + + ]: 1216 : if(band_in(iband1,isppol)) then
1940 : 768 : jband=jband+1
1941 [ - + ]: 768 : if(jband.gt.num_bands(isppol)) then
1942 : 0 : ABI_ERROR('Value of jband is above num_bands ')
1943 : : end if
1944 : 768 : A_matrix(jband,iband2,ikpt,isppol)=cmplx(amn(1,iband1,iband2,ikpt,isppol),amn(2,iband1,iband2,ikpt,isppol))
1945 : : end if
1946 : : end do !iband1
1947 : : end do !iband2
1948 : : end do !ikpt
1949 : : end do !isppol
1950 [ - + ]: 6 : ABI_FREE(amn)
1951 : : end if
1952 : :
1953 : : !********************* Projection on atomic orbitals based on .win file
1954 [ + + ]: 19 : if( lproj==2) then !based on .win file
1955 [ + + ]: 27 : nproj(:)=nwan(:)/nspinor !if spinors, then the number of projections are
1956 [ + + ]: 27 : mproj=maxval(nproj(:))
1957 : : ! half the total of wannier functions. obtain lmax and lmax2
1958 [ + + ]: 27 : lmax(:)=0
1959 [ + + ]: 27 : lmax2(:)=0
1960 : :
1961 [ + + ]: 27 : do isppol=1,nsppol
1962 [ + + ]: 89 : do iproj=1,nproj(isppol)
1963 : 89 : lmax(isppol)=max(lmax(isppol),orb_l_defs(proj_l(iproj,isppol)))
1964 : : end do !iproj
1965 : 27 : lmax2(isppol)=(lmax(isppol)+1)**2
1966 : : end do !isppol
1967 : : max_lmax=maxval(lmax(:))
1968 [ + + ]: 27 : max_lmax2=maxval(lmax2(:))
1969 : : ! Allocate arrays
1970 [ - + + - : 65 : ABI_MALLOC(ylmc_fac,(max_lmax2,mproj,nsppol))
- + + - -
+ + - + -
+ - - + -
+ ]
1971 : :
1972 : : ! get ylmfac, factor used for rotations and hybrid orbitals
1973 [ + + ]: 27 : do isppol=1,nsppol
1974 : : !print *, "nproj", nproj(isppol)
1975 : : !print *, "isppol", isppol
1976 : : !print *, ylmc_fac(1:lmax2(isppol),1:nproj(isppol),isppol)
1977 : : !print *, "lmax, lmax2: ", lmax(isppol),lmax2(isppol)
1978 : : !print *, nproj(isppol),proj_l(:,isppol),proj_m(:,isppol),proj_x(:,:,isppol)
1979 : : !print *, proj_z(:,:,isppol)
1980 : : call mlwfovlp_ylmfac(ylmc_fac(1:lmax2(isppol),1:nproj(isppol),isppol),lmax(isppol),lmax2(isppol),&
1981 [ - + - - : 27 : & mband,nproj(isppol),proj_l(:,isppol),proj_m(:,isppol),proj_x(:,:,isppol),proj_z(:,:,isppol))
- + - - -
- ]
1982 : : end do
1983 : :
1984 : 13 : norm_error=zero
1985 : 13 : norm_error_bar=zero
1986 : 13 : icg=0
1987 : :
1988 [ + + ]: 27 : do isppol=1,nsppol
1989 : : ! Allocate arrays
1990 : : ! this has to be done this way because the variable icg changes at the end of the
1991 : : ! cycle. We cannot just skip the whole cycle.
1992 [ - + + - : 56 : ABI_MALLOC(gf,(mpw,nproj(isppol)))
- + + - +
- + - - +
- + ]
1993 [ - + + - : 42 : ABI_MALLOC(gft_lm,(lmax2(isppol)))
+ - + - -
+ - + ]
1994 [ - + + - : 42 : ABI_MALLOC(gsum2,(nproj(isppol)))
+ - + - -
+ - + ]
1995 [ - + + - : 42 : ABI_MALLOC(kpg2,(mpw))
+ - + - -
+ - + ]
1996 [ - + + - : 42 : ABI_MALLOC(radial,(lmax2(isppol)))
+ - + - -
+ - + ]
1997 [ - + + - : 28 : ABI_MALLOC(ylmcp,(lmax2(isppol)))
- + - + ]
1998 : 14 : ikg=0
1999 [ + + ]: 670 : do ikpt=1, nkpt
2000 : : ! MPI: cycle over kpts not treated by this node
2001 [ - + ]: 656 : if (ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-rank)/=0) CYCLE
2002 : 656 : write(msg, '(a,i6,a,2(i0,1x))' )' processor',rank,' will compute k-point,spin=',ikpt,isppol
2003 : 656 : call wrtout(std_out, msg)
2004 : :
2005 : : ! Initialize variables
2006 : 656 : npw_k=npwarr(ikpt)
2007 [ + + ]: 4496 : gsum2(:)=0.d0
2008 [ + + + + ]: 929680 : gf(:,:) = (0.d0,0.d0)
2009 [ + + ]: 2624 : kpt(:)=dtset%kptns(:,ikpt)
2010 [ + + + + ]: 663088 : kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
2011 : :
2012 [ + + ]: 166264 : do ipw=1, npw_k
2013 : 165608 : kpg(1)= (kpt(1) + real(kg_k(1,ipw),dp)) !k+G
2014 : 165608 : kpg(2)= (kpt(2) + real(kg_k(2,ipw),dp))
2015 : 165608 : kpg(3)= (kpt(3) + real(kg_k(3,ipw),dp))
2016 : : ! Calculate modulus of k+G
2017 : 165608 : xx=gprimd(1,1)*kpg(1)+gprimd(1,2)*kpg(2)+gprimd(1,3)*kpg(3)
2018 : 165608 : yy=gprimd(2,1)*kpg(1)+gprimd(2,2)*kpg(2)+gprimd(2,3)*kpg(3)
2019 : 165608 : zz=gprimd(3,1)*kpg(1)+gprimd(3,2)*kpg(2)+gprimd(3,3)*kpg(3)
2020 : 165608 : kpg2(ipw)= two_pi*sqrt(xx**2+yy**2+zz**2)
2021 : : ! Complex Y_lm for k+G
2022 [ + + ]: 165608 : if(lmax(isppol)==0) then
2023 : 30814 : ylmcp(1)=c1/sqrt(four_pi)
2024 : : else
2025 : 134794 : call ylm_cmplx(lmax(isppol),ylmcp,xx,yy,zz)
2026 : : end if
2027 : :
2028 [ + + ]: 1042449 : do iproj=1,nproj(isppol)
2029 : : ! In PAW, we can use proj_radial > 4 to indicate that we just want the in-sphere contribution
2030 [ + + ]: 876185 : if( psps%usepaw==1) then
2031 [ - + ]: 406749 : if( just_augmentation(iproj,isppol)) cycle
2032 : : end if
2033 : : ! obtain radial part
2034 : : call mlwfovlp_radial(proj_zona(iproj,isppol),lmax(isppol),lmax2(isppol), &
2035 : 876185 : radial,proj_radial(iproj,isppol),kpg2(ipw))
2036 : : ! scale complex representation of projector orbital with radial functions of appropriate l
2037 [ + + ]: 5601682 : gft_lm(:)=radial(:)*ylmc_fac(1:lmax2(isppol),iproj,isppol)
2038 : : ! complex structure factor for projector orbital position
2039 : : arg = ( kpg(1)*proj_site(1,iproj,isppol) + &
2040 : : kpg(2)*proj_site(2,iproj,isppol) + &
2041 : 876185 : kpg(3)*proj_site(3,iproj,isppol) ) * 2*pi
2042 : 876185 : cstr_fact = cmplx(cos(arg), -sin(arg) )
2043 : :
2044 : : ! obtain guiding functions
2045 [ + + ]: 5601682 : gf(ipw,iproj)=cstr_fact*dot_product(ylmcp,gft_lm)
2046 : 1041793 : gsum2(iproj)=gsum2(iproj)+real(gf(ipw,iproj))**2+aimag(gf(ipw,iproj))**2
2047 : : end do !iproj
2048 : : end do !ipw
2049 : :
2050 [ + + ]: 4496 : do iproj=1,nproj(isppol)
2051 : : ! In PAW, we can use proj_radial > 4 to indicate that we just want the in-sphere contribution
2052 [ + + ]: 3840 : if(psps%usepaw==1 ) then
2053 [ + - ]: 2272 : if (just_augmentation(iproj,isppol)) cycle
2054 : : end if
2055 : 3840 : gsum2(iproj)=16._dp*pi**2*gsum2(iproj)/ucvol
2056 [ + + ]: 929024 : gf(:,iproj)=gf(:,iproj)/sqrt(gsum2(iproj))
2057 : 3840 : norm_error=max(abs(gsum2(iproj)-one),norm_error)
2058 : 4496 : norm_error_bar=norm_error_bar+(gsum2(iproj)-one)**2
2059 : : end do !iproj
2060 : : !
2061 : : ! Guiding functions are computed.
2062 : : ! compute overlaps of gaussian projectors and wave functions
2063 [ + + ]: 4496 : do iproj=1,nproj(isppol)
2064 : : !
2065 : : ! In PAW, we can use proj_radial > 4 to indicate that we just
2066 : : ! want the in-sphere contribution
2067 : : !
2068 [ + + ]: 3840 : if(psps%usepaw==1 ) then
2069 [ + - ]: 2272 : if ( just_augmentation(iproj,isppol)) cycle
2070 : : end if
2071 : : !
2072 : 3840 : jband=0
2073 [ + + ]: 56528 : do iband=1,mband
2074 [ + + ]: 55872 : if(band_in(iband,isppol)) then
2075 : 44800 : icg_shift=npw_k*nspinor*(iband-1)+icg
2076 : 44800 : jband=jband+1
2077 [ + + ]: 103680 : amn_tmp(:)=cmplx(0.d0,0.d0)
2078 [ + + ]: 103680 : do ispinor=1,nspinor
2079 [ + + ]: 10012872 : do ipw=1,npw_k
2080 : : !
2081 : : ! The case of spinors is tricky, we have nproj = nwan/2
2082 : : ! so we project to spin up and spin down separately, to have at
2083 : : ! the end an amn matrix with nwan projections.
2084 : 9909192 : idx=ipw*nspinor - (nspinor-ispinor)
2085 : 58880 : select type(mywfc)
2086 : : type is (cg_cprj)
2087 : 8152856 : amn_tmp(ispinor)=amn_tmp(ispinor)+gf(ipw,iproj)*cmplx(mywfc%cg(1,idx+icg_shift),-mywfc%cg(2,idx+icg_shift))
2088 : : type is (wfd_wf)
2089 : 1756336 : amn_tmp(ispinor)=amn_tmp(ispinor)+gf(ipw,iproj)*conjg(mywfc%cg_elem_complex(ipw, ispinor, iband, ikpt, isppol))
2090 : : end select
2091 : : end do !ipw
2092 : : end do !ispinor
2093 [ + + ]: 103680 : do ispinor=1,nspinor
2094 : 58880 : iwan=(iproj*nspinor)- (nspinor-ispinor)
2095 : 103680 : A_matrix(jband,iwan,ikpt,isppol)=amn_tmp(ispinor)
2096 : : end do
2097 : : end if !band_in
2098 : : end do !iband
2099 : : end do !iproj
2100 : 656 : icg=icg+npw_k*nspinor*mband
2101 : 670 : ikg=ikg+npw_k
2102 : : end do !ikpt
2103 : : ! Deallocations
2104 [ - + ]: 14 : ABI_FREE(gf)
2105 [ - + ]: 14 : ABI_FREE(gft_lm)
2106 [ - + ]: 14 : ABI_FREE(gsum2)
2107 [ - + ]: 14 : ABI_FREE(kpg2)
2108 [ - + ]: 14 : ABI_FREE(radial)
2109 [ - + ]: 27 : ABI_FREE(ylmcp)
2110 : : end do !isppol
2111 : : !
2112 : : ! if(isppol==1) then
2113 : : ! norm_error_bar=sqrt(norm_error_bar/real(nkpt*(nwan(1)),dp))
2114 : : ! else
2115 : : ! norm_error_bar=sqrt(norm_error_bar/real(nkpt*(nwan(1)+nwan(2)),dp))
2116 : : ! end if
2117 : : ! if(norm_error>0.05_dp) then
2118 : : ! write(msg, '(6a,f6.3,a,f6.3,12a)' )ch10,&
2119 : : ! & ' mlwfovlp_proj : WARNING',ch10,&
2120 : : ! & ' normalization error for wannier projectors',ch10,&
2121 : : ! & ' is',norm_error_bar,' (average) and',norm_error,' (max).',ch10,&
2122 : : ! & ' this may indicate more cell-to-cell overlap of the radial functions',ch10,&
2123 : : ! & ' than you want.',ch10,&
2124 : : ! & ' Action : modify zona (inverse range of radial functions)',ch10,&
2125 : : ! ' under "begin projectors" in ',trim(filew90_win),' file',ch10
2126 : : ! call wrtout(std_out,msg)
2127 : : ! end if
2128 : : !
2129 [ - + ]: 13 : ABI_FREE(ylmc_fac)
2130 : : end if !lproj==2
2131 : :
2132 : :
2133 : : !*************** computes projection from PROJECTORS ********************
2134 [ - + ]: 19 : if(lproj==3) then !! if LPROJPRJ
2135 : : ! ----- set values for projections --------------------- ! INPUT
2136 : : ! nbprjn:number of different l-values for projectors
2137 : : ! lprjn: value of l for each projectors par ordre croissant
2138 : : ! npprjn: number of projectors for each lprjn
2139 : 0 : natprjn=1 ! atoms with wannier functions are first
2140 : : if(natprjn/=1) then ! in this case lprjn should depend on iatprjn
2141 : : ABI_ERROR("natprjn/=1")
2142 : : end if
2143 : 0 : nbprjn=2
2144 [ # # ]: 0 : ABI_MALLOC(lprjn,(nbprjn))
2145 : 0 : lprjn(1)=0
2146 : 0 : lprjn(2)=1
2147 [ # # ]: 0 : ABI_MALLOC(npprjn,(0:lprjn(nbprjn)))
2148 : 0 : npprjn(0)=1
2149 : 0 : npprjn(1)=1
2150 : : ! --- test coherence of nbprjn and nwan
2151 : 0 : sumtmp=0
2152 [ # # ]: 0 : do iatprjn=1,natprjn
2153 [ # # ]: 0 : do libprjn=0,lprjn(nbprjn)
2154 : 0 : sumtmp=sumtmp+(2*libprjn+1)*npprjn(libprjn)
2155 : : end do
2156 : : end do
2157 [ # # ]: 0 : if(sumtmp/=nwan(1)) then
2158 : 0 : write(std_out,*) "Number of Wannier orbitals is not equal to number of projections"
2159 : 0 : write(std_out,*) "Action: check values of lprjn,npprjn % nwan"
2160 : 0 : write(std_out,*) "nwan, sumtmp=",nwan,sumtmp
2161 : 0 : ABI_ERROR("Aborting now")
2162 : : end if
2163 : : ! --- end test of coherence
2164 [ # # # # : 0 : ABI_MALLOC(amn2,(2,natom,nsppol,nkpt,mband,nspinor,nwan(1)))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
2165 [ # # ]: 0 : if(psps%usepaw==1) then
2166 [ # # # # : 0 : amn2=zero
# # # # #
# # # #
# ]
2167 : 0 : ibg=0
2168 [ # # ]: 0 : do isppol=1,nsppol
2169 [ # # ]: 0 : do ikpt=1,nkpt !TODO : hexu: check if it should be mkmem, or should skip if the kpt is not in this node.
2170 : 0 : nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
2171 [ # # ]: 0 : do iband=1,nband_k
2172 : : ! write(std_out,*)"amn2",iband,ibg,ikpt
2173 [ # # ]: 0 : do ispinor=1,nspinor
2174 : 0 : icat=1
2175 [ # # ]: 0 : do itypat=1,dtset%ntypat
2176 : 0 : lmn_size=pawtab(itypat)%lmn_size
2177 [ # # ]: 0 : do iatom=icat,icat+nattyp(itypat)-1
2178 : 0 : jj1=0
2179 [ # # ]: 0 : do ilmn=1,lmn_size
2180 [ # # ]: 0 : if(iatom.le.natprjn) then
2181 : : ! do iwan=1,nwan
2182 [ # # ]: 0 : do libprjn=0,lprjn(nbprjn)
2183 : : ! if (psps%indlmn(1,ilmn,itypat)==proj_l(iwan)) then
2184 : : ! if (psps%indlmn(2,ilmn,itypat)==mtransfo(proj_l(iwan),proj_m(iwan))) then
2185 [ # # ]: 0 : if (psps%indlmn(1,ilmn,itypat)==libprjn) then
2186 [ # # ]: 0 : if (psps%indlmn(3,ilmn,itypat)<=npprjn(libprjn)) then
2187 [ # # ]: 0 : if(band_in(iband,isppol)) then
2188 : 0 : jj1=jj1+1
2189 [ # # ]: 0 : if(jj1>nwan(isppol)) then
2190 : 0 : write(std_out,*) "number of wannier orbitals is lower than lmn_size"
2191 : 0 : write(std_out,*) jj1,nwan(isppol)
2192 : 0 : ABI_ERROR("Aborting now")
2193 : : end if
2194 : : !amn2(1,iatom,isppol,ikpt,iband,ispinor,jj1)=cprj(iatom,iband+ibg)%cp(1,ilmn)
2195 : : !amn2(2,iatom,isppol,ikpt,iband,ispinor,jj1)=cprj(iatom,iband+ibg)%cp(2,ilmn)
2196 : : amn2(1,iatom,isppol,ikpt,iband,ispinor,jj1)= &
2197 : 0 : &mywfc%cprj_elem(1, ispinor, iband, ikpt, isppol, iatom, ilmn)
2198 : : amn2(2,iatom,isppol,ikpt,iband,ispinor,jj1)= &
2199 : 0 : &mywfc%cprj_elem(2, ispinor, iband, ikpt, isppol, iatom, ilmn)
2200 : :
2201 : : !amn2(2,iatom,isppol,ikpt,iband,ispinor,jj1)=cprj(iatom,iband+ibg)%cp(2,ilmn)
2202 : : end if
2203 : : end if
2204 : : end if
2205 : : end do ! libprjn
2206 : : ! endif
2207 : : ! endif
2208 : : ! enddo ! iwan
2209 : : end if ! natprjn
2210 : : end do !ilmn
2211 : : end do ! iatom
2212 : 0 : icat=icat+nattyp(itypat)
2213 : : end do ! itypat
2214 : : end do ! ispinor
2215 : : end do !iband
2216 : 0 : ibg=ibg+nband_k*nspinor
2217 : : ! write(std_out,*)'amn2b',iband,ibg,ikpt
2218 : : end do !ikpt
2219 : : end do ! isppol
2220 : :
2221 : : ! ----------------------- Save Amn --------------------
2222 [ # # ]: 0 : do isppol=1,nsppol
2223 [ # # ]: 0 : do ikpt=1,nkpt
2224 [ # # ]: 0 : do iband2=1,nwan(isppol)
2225 : : jband=0
2226 [ # # ]: 0 : do iband1=1,mband
2227 [ # # ]: 0 : if(band_in(iband1,isppol)) then
2228 : 0 : jband=jband+1
2229 : : A_matrix(jband,iband2,ikpt,isppol)=&
2230 : 0 : cmplx(amn2(1,1,1,ikpt,iband1,1,iband2),amn2(2,1,1,ikpt,iband1,1,iband2))
2231 : : end if
2232 : : end do
2233 : : end do
2234 : : end do
2235 : : end do
2236 : : end if !usepaw
2237 [ # # ]: 0 : ABI_FREE(amn2)
2238 : 0 : ABI_FREE(npprjn)
2239 : 0 : ABI_FREE(lprjn)
2240 : :
2241 : : end if ! lproj==3
2242 : :
2243 : 19 : end subroutine mlwfovlp_proj
2244 : : !!***
2245 : :
2246 : : !!****f* m_mlwfovlp/mlwfovlp_projpaw
2247 : : !! NAME
2248 : : !! mlwfovlp_projpaw
2249 : : !!
2250 : : !! FUNCTION
2251 : : !! Calculates the functions that are given to Wannier90 as an starting guess.
2252 : : !! Here we project them inside the PAW spheres
2253 : : !!
2254 : : !! INPUTS
2255 : : !! band_in(mband)= logical array which indicates the bands to be excluded from the calculation
2256 : : !! cprj(natom,nspinor*mband*mkmem*nsppol)= <p_lmn|Cnk> coefficients for each WF |Cnk>
2257 : : !! and each |p_lmn> non-local projector
2258 : : !! just_augmentation= flag used to indicate that we are just going
2259 : : !! to compute augmentation part of the matrix
2260 : : !! and we are excluding the plane wave part.
2261 : : !! mband= maximum number of bands
2262 : : !! mkmem= number of k points which can fit in memory; set to 0 if use disk
2263 : : !! natom= number of atoms in cell.
2264 : : !! nband(nkpt*nsppol)= array cointaining number of bands at each k-point and isppol
2265 : : !! nkpt=number of k points.
2266 : : !! num_bands=number of bands actually used to construct the wannier function (NOT USED IN 6.7.1 SO WAS TEMPORARILY REMOVED)
2267 : : !! nspinor=number of spinorial components of the wavefunctions
2268 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
2269 : : !! ntypat=number of types of atoms in unit cell.
2270 : : !! nwan= number of wannier fonctions (read in wannier90.win).
2271 : : !! pawrad(ntypat)= type(pawrad_type) radial information of paw objects
2272 : : !! pawtab(ntypat)= For PAW, TABulated data initialized at start
2273 : : !! proj_l(mband)= angular part of the projection function (quantum number l)
2274 : : !! proj_m(mband)= angular part of the projection function (quantum number m)
2275 : : !! proj_radial(mband)= radial part of the projection.
2276 : : !! proj_site(3,mband)= site of the projection.
2277 : : !! proj_x(3,mband)= x axis for the projection.
2278 : : !! proj_z(3,mband)= z axis for the projection.
2279 : : !! proj_zona(mband)= extension of the radial part.
2280 : : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
2281 : : !! rprimd(3,3)= Direct lattice vectors, Bohr units.
2282 : : !! typat(natom)= atom type
2283 : : !! xred(3,natom)=reduced dimensionless atomic coordinates
2284 : : !!
2285 : : !! OUTPUT
2286 : : !! A_paw(max_num_bands,nwan,nkpt) = A matrix containing initial guess for MLWFs
2287 : : !! (augmentation part of the matrix)
2288 : : !!
2289 : : !! NOTES
2290 : : !! This routine is still under developement
2291 : : !!
2292 : : !! SOURCE
2293 : :
2294 : 0 : subroutine mlwfovlp_projpaw(A_paw,band_in,mywfc,just_augmentation,max_num_bands,mband,mkmem,&
2295 : 0 : &mwan,natom,nband,nkpt,&
2296 : 0 : &nspinor,nsppol,ntypat,nwan,pawrad,pawtab,&
2297 : 0 : &proj_l,proj_m,proj_radial,proj_site,proj_x,proj_z,proj_zona,psps,&
2298 : 0 : &rprimd,typat,xred)
2299 : :
2300 : : !Arguments ------------------------------------
2301 : : integer,intent(in) :: max_num_bands,mband,mkmem,mwan,natom,nkpt
2302 : : integer,intent(in) :: nspinor,nsppol,ntypat
2303 : : !arrays
2304 : : integer,intent(in) :: nband(nsppol*nkpt),nwan(nsppol)
2305 : : integer,intent(in) :: proj_l(mband,nsppol),proj_m(mband,nsppol),proj_radial(mband,nsppol)
2306 : : integer,intent(in) :: typat(natom)
2307 : : real(dp),intent(in):: proj_site(3,mband,nsppol)
2308 : : real(dp),intent(in) :: proj_x(3,mband,nsppol),proj_z(3,mband,nsppol),proj_zona(mband,nsppol)
2309 : : real(dp),intent(in) :: rprimd(3,3),xred(3,natom)
2310 : : complex(dp),intent(out) :: A_paw(max_num_bands,mwan,nkpt,nsppol)
2311 : : logical,intent(in) :: band_in(mband,nsppol)
2312 : : logical,intent(in)::just_augmentation(mwan,nsppol)
2313 : : !type(pawcprj_type) :: cprj(natom,nspinor*mband*mkmem*nsppol)
2314 : : type(abstract_wf), intent(inout) :: mywfc
2315 : : type(pawrad_type),intent(in) :: pawrad(ntypat)
2316 : : type(pawtab_type),intent(in) :: pawtab(ntypat)
2317 : : type(pseudopotential_type),intent(in) :: psps
2318 : :
2319 : : !Local variables-------------------------------
2320 : : !local variables
2321 : : integer :: basis_size,iatom,iband,ii
2322 : : integer :: ikpt,ir,isppol,itypat,iwan,jband
2323 : : integer :: ll,lm,ln,mm,ilmn
2324 : : integer :: lmn_size,max_lmax2, mesh_size,nn
2325 : 0 : integer :: lmax(nsppol),lmax2(nsppol)
2326 : : real(dp):: aa,int_rad2,prod_real,prod_imag
2327 : : real(dp),parameter :: dx=0.015d0,rmax=10.d0,xmin=0.d0
2328 : : real(dp):: sum,wan_lm_fac,x
2329 : : complex(dp)::prod
2330 : : character(len=500) :: msg
2331 : : !arrays
2332 : 0 : integer :: index(mband,nkpt,nsppol)
2333 : 0 : real(dp) :: dist,norm(mwan,nsppol)
2334 : 0 : real(dp) :: proj_cart(3,mwan,nsppol),proj_site_unit(3,mwan,nsppol)
2335 : 0 : real(dp) :: xcart_unit(3,natom),xred_unit(3,natom)
2336 : 0 : real(dp),allocatable :: aux(:),ff(:),r(:),int_rad(:),rad_int(:)
2337 : 0 : real(dp),allocatable :: ylmr_fac(:,:,:)
2338 : : integer,parameter :: orb_l_defs(-5:3)=(/2,2,1,1,1,0,1,2,3/) ! Tables 3.1 & 3.2, User guide
2339 : :
2340 : : ! *************************************************************************
2341 : :
2342 : : ABI_UNUSED(mkmem)
2343 : : ABI_UNUSED(nspinor)
2344 : :
2345 : 0 : write(msg, '(a,a)' )ch10,'** mlwfovlp_proj: compute in-sphere part of A_matrix'
2346 : 0 : call wrtout(std_out,msg)
2347 : :
2348 : : !Check input variables
2349 [ # # ]: 0 : do isppol=1,nsppol
2350 [ # # ]: 0 : do iwan=1,nwan(nsppol)
2351 [ # # ]: 0 : if(proj_radial(iwan,isppol)<1 .or. proj_radial(iwan,isppol)>4)then
2352 : : write(msg,'(a,a,a,i0)')&
2353 : 0 : ' proj_radial should be between 1 and 4,',ch10,&
2354 : 0 : ' however, proj_radial=',proj_radial(iwan,isppol)
2355 : 0 : ABI_BUG(msg)
2356 : : end if
2357 : : end do
2358 : : end do
2359 : :
2360 : : !Initialize
2361 [ # # # # : 0 : A_paw(:,:,:,:)=cmplx(0.d0,0.d0)
# # # # ]
2362 : :
2363 : : !Get index for cprj
2364 : 0 : ii=0
2365 [ # # ]: 0 : do isppol=1,nsppol
2366 [ # # ]: 0 : do ikpt=1,nkpt
2367 [ # # ]: 0 : do iband=1,nband(ikpt)
2368 : 0 : ii=ii+1
2369 : 0 : index(iband,ikpt,isppol)=ii
2370 : : end do
2371 : : end do
2372 : : end do
2373 : :
2374 : : !obtain lmax and lmax2
2375 [ # # ]: 0 : lmax(:)=0
2376 [ # # ]: 0 : lmax2(:)=0
2377 [ # # ]: 0 : do isppol=1,nsppol
2378 [ # # ]: 0 : do iwan=1,nwan(isppol)
2379 : 0 : lmax(isppol)=max(lmax(isppol),orb_l_defs(proj_l(iwan,isppol)))
2380 : : end do !iwan
2381 : 0 : lmax2(isppol)=(lmax(isppol)+1)**2
2382 : : end do
2383 [ # # ]: 0 : max_lmax2=maxval(lmax2(:))
2384 : : !
2385 : : !get ylmfac, factor used for rotations and hybrid orbitals
2386 : : !
2387 [ # # # # : 0 : ABI_MALLOC(ylmr_fac,(max_lmax2,mwan,nsppol))
# # # # #
# # # # #
# # # # #
# ]
2388 : :
2389 : :
2390 [ # # ]: 0 : do isppol=1,nsppol
2391 : : call mlwfovlp_ylmfar(ylmr_fac(1:lmax2(isppol),1:nwan(isppol),isppol),&
2392 : : & lmax(isppol),lmax2(isppol),mband,nwan(isppol),proj_l(:,isppol),proj_m(:,isppol),&
2393 [ # # # # : 0 : & proj_x(:,:,isppol),proj_z(:,:,isppol))
# # # # #
# ]
2394 : : !
2395 : : ! Shift projection centers and atom centers to the primitive cell
2396 : : ! This will be useful after, when we check if the Wannier function
2397 : : ! lies on one specific atom
2398 : : !
2399 [ # # # # : 0 : proj_site_unit(:,:,:)=0.d0
# # ]
2400 [ # # ]: 0 : do iwan=1,nwan(isppol)
2401 [ # # ]: 0 : do ii=1,3
2402 : 0 : proj_site_unit(ii,iwan,isppol)=ABS(proj_site(ii,iwan,isppol)-AINT(proj_site(ii,iwan,isppol)) )
2403 : : end do
2404 : : end do
2405 [ # # ]: 0 : do iatom=1,natom
2406 [ # # ]: 0 : do ii=1,3
2407 : 0 : xred_unit(ii,iatom)=ABS(xred(ii,iatom)-AINT(xred(ii,iatom)) )
2408 : : end do
2409 : : end do
2410 : 0 : call xred2xcart(natom,rprimd,xcart_unit,xred_unit)
2411 : 0 : call xred2xcart(mwan,rprimd,proj_cart(:,:,isppol),proj_site_unit(:,:,isppol))
2412 : : !
2413 : : ! Normalize the Wannier functions
2414 : : !
2415 : : ! Radial part
2416 : 0 : mesh_size= nint((rmax - xmin ) / dx + 1)
2417 [ # # # # ]: 0 : ABI_MALLOC( ff,(mesh_size))
2418 [ # # ]: 0 : ABI_MALLOC(r,(mesh_size))
2419 [ # # ]: 0 : ABI_MALLOC(rad_int,(mesh_size))
2420 [ # # ]: 0 : ABI_MALLOC(aux,(mesh_size))
2421 [ # # ]: 0 : do ir=1, mesh_size
2422 : 0 : x=xmin+DBLE(ir-1)*dx
2423 : 0 : r(ir)=x
2424 : : end do !ir
2425 [ # # ]: 0 : do iwan=1,nwan(isppol)
2426 : : ! write(std_out,*)'iwan',iwan
2427 : : ! radial functions shown in table 3.3 of wannier90 manual
2428 [ # # # # ]: 0 : if(proj_radial(iwan,isppol)==1) ff(:) = 2.d0 * proj_zona(iwan,isppol)**(1.5d0) * exp(-proj_zona(iwan,isppol)*r(:))
2429 [ # # ]: 0 : if(proj_radial(iwan,isppol)==2) ff(:) = 1.d0/(2.d0*sqrt(2.d0))*proj_zona(iwan,isppol)**(1.5d0) *&
2430 [ # # ]: 0 : & (2.d0 - proj_zona(iwan,isppol)*r(:))*exp(-proj_zona(iwan,isppol)*r(:)/2.d0)
2431 [ # # ]: 0 : if(proj_radial(iwan,isppol)==3) ff(:) = sqrt(4.d0/27.d0)*proj_zona(iwan,isppol)**(1.5d0)&
2432 : : & * (1.d0 - 2.d0*proj_zona(iwan,isppol)*r(:)/3.d0 + 2.d0*proj_zona(iwan,isppol)**2*r(:)**2/27.d0)&
2433 [ # # ]: 0 : & * exp(-proj_zona(iwan,isppol) * r(:)/3.d0)
2434 : :
2435 [ # # ]: 0 : if(proj_radial(iwan,isppol)/=4) then
2436 [ # # ]: 0 : aux(:)=ff(:)**2*r(:)**2
2437 : 0 : call simpson_int(mesh_size,dx,aux,rad_int)
2438 : 0 : sum=0.d0
2439 [ # # ]: 0 : do ir=1,mesh_size
2440 : 0 : sum=sum+rad_int(ir)
2441 : : end do
2442 : 0 : int_rad2=sum/real(mesh_size,dp)
2443 : : !
2444 : : ! do ir=1,mesh_size
2445 : : ! if(iwan==1) write(400,*)r(ir),aux(ir),rad_int(ir)
2446 : : ! end do
2447 : : else
2448 : : !
2449 : : ! ==4: gaussian function
2450 : : ! f(x)=\exp(-1/4(x/aa)**2)
2451 : : ! \int f(x)f(x) dx = \int \exp(-1/2(x/aa)**2) = aa*sqrt(2pi)
2452 : : !
2453 : 0 : int_rad2=sqrt(2.d0*pi)*proj_zona(iwan,isppol)
2454 : : end if
2455 : :
2456 : : !
2457 : : ! Now angular part
2458 : : !
2459 : 0 : prod_real=0.d0
2460 [ # # ]: 0 : do lm=1,lmax2(isppol)
2461 : 0 : wan_lm_fac=ylmr_fac(lm,iwan,isppol)
2462 : : ! write(std_out,*)'wan_lm_fac',wan_lm_fac
2463 : : ! write(std_out,*)'int_rad2',int_rad2
2464 : 0 : prod_real= prod_real + wan_lm_fac**2 * int_rad2
2465 : : end do
2466 : 0 : norm(iwan,isppol)=sqrt(prod_real)
2467 : : end do !iwan
2468 [ # # ]: 0 : ABI_FREE(ff)
2469 [ # # ]: 0 : ABI_FREE(r)
2470 [ # # ]: 0 : ABI_FREE(rad_int)
2471 [ # # ]: 0 : ABI_FREE(aux)
2472 : : !
2473 : : ! Now that we found our guiding functions
2474 : : ! We proceed with the internal product of
2475 : : ! our guiding functions and the wave function
2476 : : ! Amn=<G_m|\Psi_n> inside the sphere.
2477 : : ! The term <G_m|\Psi_n> inside the sphere is:
2478 : : ! = \sum_i <G_n | \phi_i - \tphi_i> <p_im|\Psi_m>
2479 : : !
2480 : : !
2481 : : ! G_n \phi and \tphi can be decomposed in
2482 : : ! a radial function times an angular function.
2483 : : !
2484 : : !
2485 : : ! Big loop on iwan and iatom
2486 : : !
2487 [ # # ]: 0 : do iwan=1,nwan(isppol)
2488 [ # # ]: 0 : do iatom=1,natom
2489 : : !
2490 : : ! check if center of wannier function coincides
2491 : : ! with the center of the atom
2492 : : !
2493 : : dist=((proj_cart(1,iwan,isppol)-xcart_unit(1,iatom))**2 + &
2494 : : (proj_cart(2,iwan,isppol)-xcart_unit(2,iatom))**2 + &
2495 : 0 : (proj_cart(3,iwan,isppol)-xcart_unit(3,iatom))**2)**0.5
2496 : :
2497 : : ! if the distance between the centers is major than 0.1 angstroms skip
2498 [ # # ]: 0 : if( dist > 0.188972613) cycle
2499 : 0 : write(msg, '(2a,i4,a,i4,2a)')ch10, ' Wannier function center',iwan,' is on top of atom',&
2500 : 0 : iatom,ch10,' Calculating in-sphere contribution'
2501 : 0 : call wrtout(ab_out,msg)
2502 : 0 : call wrtout(std_out,msg)
2503 : : ! Get useful quantities
2504 : 0 : itypat=typat(iatom)
2505 : 0 : lmn_size=pawtab(itypat)%lmn_size
2506 : 0 : basis_size=pawtab(itypat)%basis_size
2507 : 0 : mesh_size=pawtab(itypat)%mesh_size
2508 [ # # # # : 0 : ABI_MALLOC(int_rad,(basis_size))
# # # # #
# # # ]
2509 [ # # # # : 0 : ABI_MALLOC(ff,(mesh_size))
# # # # #
# # # #
# ]
2510 [ # # # # : 0 : ABI_MALLOC(aux,(mesh_size))
# # # # ]
2511 : :
2512 : : ! Integrate first the radial part and save it into an array
2513 : : ! radial functions shown in table 3.3 of wannier90 manual
2514 [ # # ]: 0 : if(proj_radial(iwan,isppol)==1) aux(1:mesh_size) = 2.d0 * proj_zona(iwan,isppol)**(1.5d0) *&
2515 [ # # ]: 0 : & exp(-proj_zona(iwan,isppol)*pawrad(itypat)%rad(1:mesh_size))
2516 [ # # ]: 0 : if(proj_radial(iwan,isppol)==2) aux(1:mesh_size) = 1.d0/(2.d0*sqrt(2.d0))*proj_zona(iwan,isppol)**(1.5d0) *&
2517 : : & (2.d0 - proj_zona(iwan,isppol)*pawrad(itypat)%rad(1:mesh_size)) &
2518 [ # # ]: 0 : & * exp(-proj_zona(iwan,isppol)*pawrad(itypat)%rad(1:mesh_size)/2.d0)
2519 [ # # ]: 0 : if(proj_radial(iwan,isppol)==3) aux(1:mesh_size) = sqrt(4.d0/27.d0)*proj_zona(iwan,isppol)**(1.5d0)&
2520 : : & * (1.d0 - 2.d0*proj_zona(iwan,isppol)*pawrad(itypat)%rad(1:mesh_size)/3.d0 &
2521 : : & + 2.d0*proj_zona(iwan,isppol)**2 *pawrad(itypat)%rad(1:mesh_size)**2/27.d0)&
2522 [ # # ]: 0 : & * exp(-proj_zona(iwan,isppol) * pawrad(itypat)%rad(1:mesh_size)/3.d0)
2523 : : !
2524 : : ! ==4: gaussian function
2525 : : ! f(x)=\exp(-1/4(x/aa)**2)
2526 : : !
2527 [ # # ]: 0 : if(proj_radial(iwan,isppol)==4) then
2528 : 0 : aa=1.d0/proj_zona(iwan,isppol)
2529 [ # # ]: 0 : aux(1:mesh_size)= exp(-0.25d0*(pawrad(itypat)%rad(1:mesh_size)*aa)**2)
2530 : : end if
2531 : : !
2532 : : ! Normalize aux
2533 [ # # ]: 0 : aux(:)=aux(:)/norm(iwan,isppol)
2534 : : !
2535 [ # # ]: 0 : do ln=1,basis_size
2536 [ # # ]: 0 : if(just_augmentation(iwan,isppol)) then
2537 : : !
2538 : : ! just augmentation region contribution
2539 : : ! In this case there is no need to use \tphi
2540 : : ! ff= \int R_wan(r) (R_phi(ln;r)/r ) r^2 dr
2541 : : !
2542 : : ff(1:mesh_size)= aux(1:mesh_size) * pawtab(itypat)%phi(1:mesh_size,ln) &
2543 [ # # ]: 0 : & * pawrad(itypat)%rad(1:mesh_size)
2544 : : else
2545 : : ! Inside sphere contribution = \phi - \tphi
2546 : : ! ff= \int R_wan(r) (R_phi(ln;r)/r - R_tphi(ln;r)/r) r^2 dr
2547 : : ff(1:mesh_size)= aux(1:mesh_size) * (pawtab(itypat)%phi(1:mesh_size,ln)-pawtab(itypat)%tphi(1:mesh_size,ln)) &
2548 [ # # ]: 0 : & * pawrad(itypat)%rad(1:mesh_size)
2549 : : end if
2550 : : !
2551 : : ! Integration with simpson routine
2552 : : !
2553 : 0 : call simp_gen(int_rad(ln),ff,pawrad(itypat))
2554 : : ! do ii=1,mesh_size
2555 : : ! unit_ln=400+ln
2556 : : ! if( iwan==1 ) write(unit_ln,*)pawrad(itypat)%rad(ii),ff(ii),int_rad(ln)
2557 : : ! end do
2558 : : end do !ln
2559 [ # # ]: 0 : ABI_FREE(ff)
2560 [ # # ]: 0 : ABI_FREE(aux)
2561 : : !
2562 : : ! Now integrate the angular part
2563 : : ! Cycle on i indices
2564 : : !
2565 : : ! prod_real=0.d0
2566 [ # # ]: 0 : do ilmn=1, lmn_size
2567 : 0 : ll=Psps%indlmn(1,ilmn,itypat)
2568 : 0 : mm=Psps%indlmn(2,ilmn,itypat)
2569 : 0 : nn=Psps%indlmn(3,ilmn,itypat)
2570 : 0 : lm=Psps%indlmn(4,ilmn,itypat)
2571 : 0 : ln=Psps%indlmn(5,ilmn,itypat)
2572 : : ! write(std_out,*)'ll ',ll,' mm ',mm,'nn',nn,"lm",lm,"ln",ln
2573 : : !
2574 : : ! Get wannier factor for that lm component
2575 [ # # ]: 0 : if(lm <=lmax2(isppol)) then
2576 : 0 : wan_lm_fac=ylmr_fac(lm,iwan,isppol)
2577 : : ! Make delta product
2578 : : ! Here we integrate the angular part
2579 : : ! Since the integral of the product of two spherical harmonics
2580 : : ! is a delta function
2581 [ # # ]: 0 : if( abs(wan_lm_fac) > 0.0d0) then
2582 : : ! write(std_out,*) 'll',ll,'mm',mm,'lm',lm,'ln',ln,'factor',wan_lm_fac !lm index for wannier function
2583 : : !
2584 : : ! Calculate Amn_paw, now that the radial and angular integrations are done
2585 : : !
2586 : 0 : prod=cmplx(0.d0,0.d0)
2587 [ # # ]: 0 : do ikpt=1,nkpt
2588 : 0 : jband=0
2589 : : ! NOTE: hexu: this doesn't seem right for nspinor=2
2590 : : ! NOTE: also nband size is (nsppol*nkpt)
2591 [ # # ]: 0 : do iband=1,nband(ikpt)
2592 [ # # ]: 0 : if(band_in(iband,isppol)) then
2593 : 0 : jband=jband+1
2594 : :
2595 : : !prod_real= cprj(iatom,index(iband,ikpt,isppol))%cp(1,ilmn) * int_rad(ln) * wan_lm_fac
2596 : : !prod_imag= cprj(iatom,index(iband,ikpt,isppol))%cp(2,ilmn) * int_rad(ln) * wan_lm_fac
2597 : : ! FIXME: here ispinor is set to 1
2598 : : ! There should be a loop over ispinor
2599 : 0 : prod_real= mywfc%cprj_elem(1, 1, iband, ikpt, isppol, iatom, ilmn ) * int_rad(ln) * wan_lm_fac
2600 : 0 : prod_imag= mywfc%cprj_elem(2, 1, iband, ikpt, isppol, iatom, ilmn ) * int_rad(ln) * wan_lm_fac
2601 : 0 : prod=cmplx(prod_real,prod_imag)
2602 : :
2603 : 0 : A_paw(jband,iwan,ikpt,isppol)=A_paw(jband,iwan,ikpt,isppol)+prod
2604 : : end if !band_in
2605 : : end do !iband
2606 : : end do !ikpt
2607 : : !
2608 : : end if !lm<=lmax2
2609 : : end if ! abs(wan_lm_fac) > 0.0d0
2610 : : end do !ilmn=1, lmn_size
2611 [ # # ]: 0 : ABI_FREE(int_rad)
2612 : : end do !iatom
2613 : : end do !iwan
2614 : : end do !isppol
2615 : :
2616 : : !Deallocate quantities
2617 [ # # ]: 0 : ABI_FREE(ylmr_fac)
2618 : :
2619 [ # # ]: 0 : end subroutine mlwfovlp_projpaw
2620 : : !!***
2621 : :
2622 : : !!****f* m_mlwfovlp/mlwfovlp_radial
2623 : : !! NAME
2624 : : !! mlwfovlp_radial
2625 : : !!
2626 : : !! FUNCTION
2627 : : !! Calculates the radial part of the initial functions given to Wannier90
2628 : : !! as an starting point for the minimization.
2629 : : !! The trial functions are a set of solutions to the radial part of the hydrogenic
2630 : : !! Schrodinger equation as it is explained in Table 3.3 of the Wannier90 user guide.
2631 : : !!
2632 : : !! INPUTS
2633 : : !! alpha= Z/a = zona
2634 : : !! lmax= maximum value of l
2635 : : !! rvalue= integer defining the choice for radial functions R(r).
2636 : : !! It can take values from 1-3.
2637 : : !! It is associted to the radial part of the hydrogenic Schrodinger equation for l=0,
2638 : : !! See the manual of Wannier90 for more information. (www.wannier.org)
2639 : : !! xx= scalar number used to calculate the spherical bessel function. J_il(xx)
2640 : : !!
2641 : : !! OUTPUT
2642 : : !! mlwfovlp_radial= radial part for initial projections used to construct MLWF
2643 : : !!
2644 : : !! SIDE EFFECTS
2645 : : !! None
2646 : : !!
2647 : : !! NOTES
2648 : : !! Calculates the radial part of the initial functions given as an initial
2649 : : !! guess by the user to construct the MLWF.
2650 : : !!
2651 : : !! SOURCE
2652 : :
2653 : 876185 : subroutine mlwfovlp_radial(alpha,lmax,lmax2,radial,rvalue,xx)
2654 : :
2655 : : !Arguments ------------------------------------
2656 : : !scalars
2657 : : integer,intent(in) :: lmax,lmax2,rvalue
2658 : : real(dp),intent(in) :: alpha,xx
2659 : : !arrays
2660 : : real(dp),intent(out) :: radial(lmax2)
2661 : :
2662 : : !Local variables
2663 : : !scalars
2664 : : integer :: ir,ll,lm,mesh,mm
2665 : : real(dp),parameter :: dx=0.015d0,rmax=10.d0,xmin=0.d0
2666 : : real(dp) :: aa,ftmp,gauss,rtmp,x
2667 : : character(len=500) :: msg
2668 : : !arrays
2669 : : real(dp),parameter :: dblefact(4)=(/1_dp,3_dp,15_dp,105_dp/)
2670 : 876185 : real(dp),allocatable :: aux(:),bes(:),cosr(:),func_r(:),r(:),rad_int(:),sinr(:)
2671 : :
2672 : : ! *************************************************************************
2673 : :
2674 : : !Radial functions in the form of hydrogenic orbitals as defined in the
2675 : : !wannier90 manual.
2676 [ + + ]: 876185 : if(( rvalue > 0 ).and.(rvalue < 4)) then
2677 : :
2678 : : ! mesh
2679 : 710529 : mesh= nint((rmax - xmin ) / dx + 1)
2680 [ - + ]: 710529 : ABI_MALLOC( bes,(mesh))
2681 [ - + ]: 710529 : ABI_MALLOC(func_r,(mesh))
2682 [ - + ]: 710529 : ABI_MALLOC(r,(mesh))
2683 [ - + ]: 710529 : ABI_MALLOC(rad_int,(mesh))
2684 [ - + ]: 710529 : ABI_MALLOC( aux,(mesh))
2685 [ - + ]: 710529 : ABI_MALLOC(cosr,(mesh))
2686 [ - + ]: 710529 : ABI_MALLOC(sinr,(mesh))
2687 [ + + ]: 475343901 : do ir=1, mesh
2688 : 474633372 : x=xmin+DBLE(ir-1)*dx
2689 : 475343901 : r(ir)=x
2690 : : end do !ir
2691 : :
2692 : : ! radial functions shown in table 3.3 of wannier90 manual
2693 [ + - + + ]: 475343901 : if (rvalue==1) func_r(:) = 2.d0 * alpha**(3.d0/2.d0) * exp(-alpha*r(:))
2694 [ - + ]: 710529 : if (rvalue==2) func_r(:) = 1.d0/(2.d0*sqrt(2.d0))*alpha**(3.d0/2.d0) *&
2695 [ # # ]: 0 : & (2.d0 - alpha*r(:))*exp(-alpha*r(:)/2.d0)
2696 [ - + ]: 710529 : if (rvalue==3) func_r(:) = sqrt(4.d0/27.d0)*alpha**(3.d0/2.d0)&
2697 : : & * (1.d0 - 2.d0*alpha*r(:)/3.d0 + 2.d0*alpha**2*r(:)**2/27.d0)&
2698 [ # # ]: 0 : & * exp(-alpha * r(:)/3.d0)
2699 : :
2700 : : ! compute spherical bessel functions
2701 [ + + ]: 475343901 : cosr(:)=cos(xx*r(:))
2702 [ + + ]: 475343901 : sinr(:)=sin(xx*r(:))
2703 : 710529 : lm=0
2704 [ + + ]: 2374640 : do ll=0,lmax
2705 : 1664111 : call besjm(xx,bes,cosr,ll,mesh,sinr,r)
2706 [ + + ]: 1113290259 : aux(:)=bes(:)*func_r(:)*r(:)
2707 : : ! do ir=1,mesh
2708 : : ! write(310,*) r(ir),bes(ir)
2709 : : ! end do
2710 : 1664111 : call simpson_int(mesh,dx,aux,rad_int)
2711 : 1664111 : rtmp=rad_int(mesh)/mesh
2712 [ + + ]: 6582125 : do mm=-ll,ll
2713 : 4207485 : lm=lm+1
2714 : 5871596 : radial(lm)=rtmp
2715 : : end do !mm
2716 : : end do !ll
2717 [ - + ]: 710529 : ABI_FREE(bes)
2718 [ - + ]: 710529 : ABI_FREE(func_r)
2719 [ - + ]: 710529 : ABI_FREE(r)
2720 [ - + ]: 710529 : ABI_FREE(aux)
2721 [ - + ]: 710529 : ABI_FREE(rad_int)
2722 [ - + ]: 710529 : ABI_FREE(cosr)
2723 [ - + ]: 710529 : ABI_FREE(sinr)
2724 : :
2725 : : ! Radial part in the form of Gaussian functions of a given width
2726 : : ! Taken by code of made by drh.
2727 [ + - ]: 165656 : elseif ( rvalue == 4) then
2728 : 165656 : aa=1._dp/alpha
2729 : 165656 : gauss=exp(-0.25_dp*(aa*xx)**2)
2730 : 165656 : lm=0
2731 [ + + ]: 448764 : do ll=0,lmax
2732 : 283108 : ftmp=(0.5_dp*pi)**(0.25_dp)*aa*sqrt(aa/dblefact(ll+1))*(aa*xx)**ll*gauss
2733 [ + + ]: 966776 : do mm=-ll,ll
2734 : 518012 : lm=lm+1
2735 : 801120 : radial(lm)=ftmp
2736 : : end do
2737 : : end do
2738 : : else ! rvalue < 0 of rvalue > 4
2739 : : write(msg,'(a,i6,5a)')&
2740 : 0 : ' Radial function r=',rvalue,ch10,&
2741 : 0 : ' is not defined',ch10,&
2742 : 0 : ' Modify .win file',ch10
2743 : 0 : ABI_BUG(msg)
2744 : : end if !rvalue
2745 : :
2746 : 876185 : end subroutine mlwfovlp_radial
2747 : : !!***
2748 : :
2749 : : !!****f* m_mlwfovlp/mlwfovlp_ylmfac
2750 : : !! NAME
2751 : : !! mlwfovlp_ylmfac
2752 : : !!
2753 : : !! FUNCTION
2754 : : !! Routine that produces a factor by which the initial
2755 : : !! guess of functions will be multiplied for the Wannier90 interface.
2756 : : !! It is just used if there are rotations, or if the functions required
2757 : : !! are linear combinations of the ylm real functions.
2758 : : !!
2759 : : !! Example,
2760 : : !! For a function G(r)= 1/2 s + 1/3 px - 1/2 pz
2761 : : !! it would produce a matrix of the following form:
2762 : : !! [1/2,-1/2,1/3,0,0...0]
2763 : : !!
2764 : : !! The real spherical harmonics are given as factors of complex spherical harmonics
2765 : : !! The real spherical harmonics are given in table 3.1 of Wannier90 user guide.
2766 : : !!
2767 : : !! INPUTS
2768 : : !! lmax= maximum l value for spherical harmonics
2769 : : !! lmax2=number of ylm functions
2770 : : !! mband=maximum number of bands
2771 : : !! nwan = number of wannier functions
2772 : : !! proj_l(mband)= angular part of the projection function (quantum number l)
2773 : : !! proj_m(mband)= angular part of the projection function (quantum number m)
2774 : : !! proj_x(3,mband)= x axis for the projection.
2775 : : !! proj_z(3,mband)= z axis for the projection.
2776 : : !!
2777 : : !! OUTPUT
2778 : : !! ylmc_fac(lmax2,nwan)=matrix containig a factor for ylm hybrid orbitals
2779 : : !!
2780 : : !! SIDE EFFECTS
2781 : : !! (only writing, printing)
2782 : : !!
2783 : : !! SOURCE
2784 : :
2785 : :
2786 : 14 : subroutine mlwfovlp_ylmfac(ylmc_fac,lmax,lmax2,mband,nwan,proj_l,proj_m,proj_x,proj_z)
2787 : :
2788 : : !Arguments ------------------------------------
2789 : : integer, intent(in):: lmax,lmax2,nwan,mband
2790 : : ! arrays
2791 : : integer,intent(in) :: proj_l(mband),proj_m(mband)
2792 : : real(dp),intent(in) :: proj_x(3,mband),proj_z(3,mband)
2793 : : complex(dp),intent(out)::ylmc_fac(lmax2,nwan)
2794 : : !
2795 : : !Local variables-------------------------------
2796 : : !
2797 : : integer :: orb_idx(16)=(/1,3,4,2,7,8,6,9,5,13,14,12,15,11,16,10/) !Tab3.1 Wannier90 user guide
2798 : : integer :: idum,ii,info,inversion_flag
2799 : : integer :: ir,iwan,jj,ll,lm,lmc,mm,mr
2800 : : real(dp):: onem,test
2801 : : ! arrays
2802 : 28 : integer:: ipiv(lmax2)
2803 : 28 : real(dp)::r(3,lmax2),rp(3,lmax2)
2804 : : real(dp)::rs2,rs3,rs6,rs12,umat(3,3)
2805 : 28 : complex(dp)::crot(lmax2,lmax2),ctor(lmax2,lmax2),orb_lm(lmax2,-5:3,7)
2806 : 28 : complex(dp):: ylmcp(lmax2)
2807 : 28 : complex(dp):: ylmc_rr(lmax2,lmax2),ylmc_rr_save(lmax2,lmax2)
2808 : 28 : complex(dp):: ylmc_rrinv(lmax2,lmax2),ylmc_rp(lmax2,lmax2)
2809 : : complex(dp),parameter :: c0=(0._dp,0._dp),c1=(1._dp,0._dp),ci=(0._dp,1._dp)
2810 : : character(len=500) :: msg
2811 : :
2812 : : ! *************************************************************************
2813 : :
2814 : :
2815 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2816 : : !DEBUG
2817 : : !write(std_out,*)'lmax ',lmax,'lmax2 ',lmax2
2818 : : !write(std_out,*)'mband ',mband,'nwan ',nwan
2819 : : !
2820 : : !do iwan=1,nwan
2821 : : !write(std_out,*)'iwan,proj_l, proj_m',proj_l(iwan),proj_m(iwan)
2822 : : !write(std_out,*)'iwan,proj_x, proj_z',iwan,proj_x(:,iwan),proj_z(:,iwan)
2823 : : !end do
2824 : : !!END DEBUG
2825 : :
2826 : : !constants for linear combinations of ylm's
2827 : 14 : rs2=1._dp/sqrt(2._dp)
2828 : 14 : rs3=1._dp/sqrt(3._dp)
2829 : 14 : rs6=1._dp/sqrt(6._dp)
2830 : 14 : rs12=1._dp/sqrt(12._dp)
2831 : :
2832 : : !complex lm coefficients for real spherical harmonics in conventional order
2833 : : !s, py,pz,px, dxy,dyz,dz2,dxz,dx2-y2, fy(3x2-y2),fxyz,fyz2,fz3,fxz2,
2834 : : !fz(x2-y2),fx(x2-3y2)
2835 [ + + + + ]: 468 : ctor(:,:)=c0
2836 [ + + ]: 43 : do ll=0,lmax
2837 : 29 : mm=0
2838 : 29 : lm= ll**2+ll+mm+1
2839 : 29 : ctor(lm,lm)=c1
2840 [ + + ]: 43 : if(ll>0) then
2841 : : onem=one
2842 [ + + ]: 33 : do mm=1,ll
2843 : 18 : onem=-onem !(-1^mm)
2844 : 18 : lm= ll**2+ll+mm+1
2845 : 18 : lmc=ll**2+ll-mm+1
2846 : 18 : ctor(lm ,lm )=rs2*c1
2847 : 18 : ctor(lmc,lm )=onem*rs2*c1
2848 : 18 : ctor(lm ,lmc)=rs2*ci
2849 : 33 : ctor(lmc,lmc)=-onem*rs2*ci
2850 : : end do
2851 : : end if
2852 : : end do
2853 : :
2854 : : lm=0
2855 [ + + ]: 43 : do ll=0,lmax
2856 [ + + ]: 108 : do mm=-ll,ll
2857 : 65 : lm=lm+1
2858 [ + + ]: 483 : ctor(:,lm)=ctor(:,lm)*conjg(ci)**ll
2859 : : end do !mm
2860 : : end do !ll
2861 : :
2862 : :
2863 : : !coefficients for basic wannier orbitals in Table 3.1 order
2864 [ + + + + : 5089 : orb_lm(:,:,:)=c0
+ + ]
2865 : : ii=0
2866 [ + + ]: 43 : do ll=0,lmax
2867 [ + + ]: 108 : do mr=1,2*ll+1
2868 : 65 : ii=ii+1
2869 [ + + ]: 483 : orb_lm(:,ll,mr)=ctor(:,orb_idx(ii))
2870 : : end do
2871 : : end do
2872 : :
2873 : :
2874 : :
2875 : : !coefficients for linear combinations in table 3.2 order
2876 [ + + ]: 14 : if(lmax>=1) then
2877 : : ! s px
2878 [ + + ]: 75 : orb_lm(:,-1,1)=rs2*ctor(:,1)+rs2*ctor(:,4)
2879 [ + + ]: 75 : orb_lm(:,-1,2)=rs2*ctor(:,1)-rs2*ctor(:,4)
2880 : : ! s px py
2881 [ + + ]: 75 : orb_lm(:,-2,1)=rs3*ctor(:,1)-rs6*ctor(:,4)+rs2*ctor(:,2)
2882 [ + + ]: 75 : orb_lm(:,-2,2)=rs3*ctor(:,1)-rs6*ctor(:,4)-rs2*ctor(:,2)
2883 [ + + ]: 75 : orb_lm(:,-2,3)=rs3*ctor(:,1)+2._dp*rs6*ctor(:,4)
2884 : : ! s px py pz
2885 [ + + ]: 75 : orb_lm(:,-3,1)=half*(ctor(:,1)+ctor(:,4)+ctor(:,2)+ctor(:,3))
2886 [ + + ]: 75 : orb_lm(:,-3,2)=half*(ctor(:,1)+ctor(:,4)-ctor(:,2)-ctor(:,3))
2887 [ + + ]: 75 : orb_lm(:,-3,3)=half*(ctor(:,1)-ctor(:,4)+ctor(:,2)-ctor(:,3))
2888 [ + + ]: 75 : orb_lm(:,-3,4)=half*(ctor(:,1)-ctor(:,4)-ctor(:,2)+ctor(:,3))
2889 : : end if
2890 [ + + ]: 14 : if(lmax>=2) then
2891 : : ! s px py
2892 [ + + ]: 30 : orb_lm(:,-4,1)=rs3*ctor(:,1)-rs6*ctor(:,4)+rs2*ctor(:,2)
2893 [ + + ]: 30 : orb_lm(:,-4,2)=rs3*ctor(:,1)-rs6*ctor(:,4)-rs2*ctor(:,2)
2894 [ + + ]: 30 : orb_lm(:,-4,3)=rs3*ctor(:,1)+2._dp*rs6*ctor(:,4)
2895 : : ! pz dz2
2896 [ + + ]: 30 : orb_lm(:,-4,4)= rs2*ctor(:,3)+rs2*ctor(:,7)
2897 [ + + ]: 30 : orb_lm(:,-4,5)=-rs2*ctor(:,3)+rs2*ctor(:,7)
2898 : : ! s px dz2 dx2-y2
2899 [ + + ]: 30 : orb_lm(:,-5,1)=rs6*ctor(:,1)-rs2*ctor(:,4)-rs12*ctor(:,7)+half*ctor(:,9)
2900 [ + + ]: 30 : orb_lm(:,-5,2)=rs6*ctor(:,1)+rs2*ctor(:,4)-rs12*ctor(:,7)+half*ctor(:,9)
2901 : : ! s py dz2 dx2-y2
2902 [ + + ]: 30 : orb_lm(:,-5,3)=rs6*ctor(:,1)-rs2*ctor(:,2)-rs12*ctor(:,7)-half*ctor(:,9)
2903 [ + + ]: 30 : orb_lm(:,-5,4)=rs6*ctor(:,1)+rs2*ctor(:,2)-rs12*ctor(:,7)-half*ctor(:,9)
2904 : : ! s pz dz2
2905 [ + + ]: 30 : orb_lm(:,-5,5)=rs6*ctor(:,1)-rs2*ctor(:,3)+rs3*ctor(:,7)
2906 [ + + ]: 30 : orb_lm(:,-5,6)=rs6*ctor(:,1)+rs2*ctor(:,3)+rs3*ctor(:,7)
2907 : : end if
2908 : :
2909 : : !stuff complex wannier orbital coefficient array
2910 [ + + ]: 89 : do iwan=1,nwan
2911 [ + + ]: 500 : ylmc_fac(:,iwan)=orb_lm(:,proj_l(iwan),proj_m(iwan))
2912 : : end do
2913 : :
2914 : :
2915 : : !setup to rotate ylmc_fac to new axes if called for
2916 : : !skip if only s projectors are used
2917 [ + + ]: 14 : if ( lmax>0 ) then
2918 : : ! generate a set of nr=lmax2 random vectors
2919 : : ! idum=123456
2920 [ + + ]: 75 : do ir=1,lmax2
2921 [ + + ]: 252 : do ii=1,3
2922 : 252 : r(ii,ir) = uniformrandom(idum)-0.5d0
2923 : : end do !ii
2924 : 63 : call ylm_cmplx(lmax,ylmcp,r(1,ir),r(2,ir),r(3,ir))
2925 [ + + ]: 450 : ylmc_rr(ir,:)=conjg(ylmcp(:))
2926 [ + + ]: 462 : ylmc_rr_save(ir,:)=conjg(ylmcp(:))
2927 : : end do !ir
2928 : :
2929 [ + + + + ]: 462 : ylmc_rrinv(:,:)=c0
2930 [ + + ]: 75 : do ii=1,lmax2
2931 : 75 : ylmc_rrinv(ii,ii)=c1
2932 : : end do !ii
2933 : : ! calculate inverse of ylmc(ir,lm) matrix
2934 : 12 : call ZGESV(lmax2,lmax2,ylmc_rr,lmax2,ipiv,ylmc_rrinv,lmax2,info)
2935 : :
2936 : : ! check that r points are independent (ie., that matrix inversion wasn't
2937 : : ! too close to singular)
2938 [ + - + + : 3675 : ylmc_rr=matmul(ylmc_rrinv,ylmc_rr_save)
+ + + + +
+ + + ]
2939 : 12 : test=zero
2940 [ + + ]: 75 : do ii=1,lmax2
2941 : 63 : ylmc_rr(ii,ii)=ylmc_rr(ii,ii)-c1
2942 [ + + ]: 462 : do jj=1,lmax2
2943 : 450 : test=max(abs(ylmc_rr(ii,jj)),test)
2944 : : end do !ii
2945 : : end do !jj
2946 [ - + ]: 12 : if(test>tol8) then
2947 : : write(msg, '(5a)' )&
2948 : 0 : & ' matrix inversion error for wannier rotations',ch10,&
2949 : 0 : & ' random vectors r(j,1:nr) are not all independent !! ',ch10,&
2950 : 0 : & ' Action : re-seed uniformrandom or maybe just try again'
2951 : 0 : ABI_ERROR(msg)
2952 : : end if !test>tol8
2953 : :
2954 : : ! end of the preliminaries, now to the rotations of the wannier orbitals
2955 [ + + ]: 79 : do iwan=1,nwan
2956 : : ! don't bother for s orbitals
2957 [ + + ]: 67 : if(proj_l(iwan)==0) cycle
2958 : : ! check for default axes and cycle if found
2959 : : if(proj_z(1,iwan)==zero .and. proj_z(2,iwan)==zero .and.&
2960 : : & proj_z(3,iwan)== one .and. proj_x(1,iwan)==one .and.&
2961 [ + - + - : 63 : & proj_x(2,iwan)==zero .and. proj_x(3,iwan)==zero) cycle
+ - + + +
- + - ]
2962 : :
2963 : : ! get the u matrix that rotates the reference frame
2964 : 4 : call rotmat(proj_x(:,iwan),proj_z(:,iwan),inversion_flag,umat)
2965 : :
2966 : : ! find rotated r-vectors. Optional inversion
2967 : : ! operation is an extension of the wannier90 axis-setting options
2968 : : ! which only allow for proper axis rotations
2969 [ - + ]: 4 : if(inversion_flag==1) then
2970 [ # # # # : 0 : rp(:,:)= -matmul ( umat(:,:), r(:,:) )
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
2971 : : else
2972 [ + - + + : 276 : rp(:,:) = matmul ( umat(:,:) , r(:,:) )
+ + + + +
+ + + ]
2973 : : end if !inversion_flag
2974 : :
2975 [ + + ]: 20 : do ir=1,lmax2
2976 : : ! get the ylm representation of the rotated vectors
2977 : 16 : call ylm_cmplx(lmax,ylmcp,rp(1,ir),rp(2,ir),rp(3,ir))
2978 [ + + ]: 84 : ylmc_rp(ir,:)=conjg(ylmcp(:))
2979 : : end do !ir
2980 : : ! the matrix product sum(ir) ylmc_rrinv(lm,ir)*ylmc_rp(ir,lm') gives the
2981 : : ! the complex lmXlm matrix representation of the coordinate rotation
2982 [ + - + + : 420 : crot(:,:)=matmul(ylmc_rrinv(:,:),ylmc_rp(:,:))
+ + + + +
+ + + ]
2983 : :
2984 : : ! now rotate the current wannier orbital
2985 [ + + + + : 100 : ylmcp(:)=matmul(crot(:,:),ylmc_fac(:,iwan))
+ + ]
2986 [ + + ]: 91 : ylmc_fac(:,iwan)=ylmcp(:)
2987 : :
2988 : : ! write(std_out,*)'ylmc_fac',ylmc_fac(:,iwan)
2989 : : end do !iwan
2990 : : end if !lmax>0
2991 : :
2992 : 14 : end subroutine mlwfovlp_ylmfac
2993 : : !!***
2994 : :
2995 : : !!****f* m_mlwfovlp/mlwfovlp_ylmfar
2996 : : !! NAME
2997 : : !! mlwfovlp_ylmfar
2998 : : !!
2999 : : !! FUNCTION
3000 : : !! Routine that produces a fator by which the initial
3001 : : !! guess of functions will be multiplied for the Wannier90 interface.
3002 : : !! It is just used if there are rotations, or if the functions required
3003 : : !! are linear combinations of the ylm real functions.
3004 : : !!
3005 : : !! Example,
3006 : : !! For a function G(r)= 1/2 s + 1/3 px - 1/2 pz
3007 : : !! it would produce a matrix of the following form:
3008 : : !! [1/2,-1/2,1/3,0,0...0]
3009 : : !!
3010 : : !! This function is similar to mlwfovlp_ylmfac, but the factors it uses
3011 : : !! real spherical harmonics instead of complex
3012 : : !! spherical harmonics. Remember that real spherical harmonics
3013 : : !! are linear combinations of complex
3014 : : !! spherical harmonics
3015 : : !!
3016 : : !! INPUTS
3017 : : !! lmax= maximum l value for spherical harmonics
3018 : : !! lmax2=number of ylm functions
3019 : : !! mband=maximum number of bands
3020 : : !! nwan = number of wannier functions
3021 : : !! proj_l(mband)= angular part of the projection function (quantum number l)
3022 : : !! proj_m(mband)= angular part of the projection function (quantum number m)
3023 : : !! proj_x(3,mband)= x axis for the projection.
3024 : : !! proj_z(3,mband)= z axis for the projection.
3025 : : !!
3026 : : !! OUTPUT
3027 : : !! ylmc_fac(lmax2,nwan)=matrix containig a factor for ylm hybrid orbitals
3028 : : !!
3029 : : !! SOURCE
3030 : :
3031 : 0 : subroutine mlwfovlp_ylmfar(ylmr_fac,lmax,lmax2,mband,nwan,proj_l,proj_m,proj_x,proj_z)
3032 : :
3033 : : !Arguments ------------------------------------
3034 : : integer, intent(in):: lmax,lmax2,nwan,mband
3035 : : ! arrays
3036 : : integer,intent(in) :: proj_l(mband),proj_m(mband)
3037 : : real(dp),intent(in) :: proj_x(3,mband),proj_z(3,mband)
3038 : : real(dp),intent(out)::ylmr_fac(lmax2,nwan)
3039 : : !
3040 : : !Local variables-------------------------------
3041 : : !
3042 : : integer :: idum,ii,inversion_flag
3043 : : integer :: ir,iwan,jj,ll,lm,mm,mr
3044 : : real(dp) :: onem,test
3045 : : ! arrays
3046 : 0 : real(dp),allocatable:: dummy(:,:),nrm(:)
3047 : 0 : real(dp) :: r(3,lmax2),rp(3,lmax2)
3048 : : real(dp) :: rs2,rs3,rs6,rs12,umat(3,3)
3049 : 0 : real(dp) :: rot(lmax2,lmax2),tor(lmax2,lmax2),orb_lm(lmax2,-5:3,7)
3050 : 0 : real(dp) :: ylmrp(lmax2)
3051 : 0 : real(dp) :: ylmr_rr(lmax2,lmax2),ylmr_rr_save(lmax2,lmax2)
3052 : 0 : real(dp) :: ylmr_rrinv(lmax2,lmax2),ylmr_rp(lmax2,lmax2)
3053 : : character(len=500) :: msg ! to be uncommented, if needed
3054 : : !integer :: orb_idx(16)=(/1,3,4,2,7,8,6,9,5,13,14,12,15,11,16,10/) !Tab3.1 Wannier90 user guide
3055 : :
3056 : : ! *************************************************************************
3057 : :
3058 : : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3059 : : !DEBUG
3060 : : !write(std_out,*)'lmax ',lmax,'lmax2 ',lmax2
3061 : : !write(std_out,*)'mband ',mband,'nwan ',nwan
3062 : : !
3063 : : !do iwan=1,nwan
3064 : : !write(std_out,*)'iwan,proj_l, proj_m',proj_l(iwan),proj_m(iwan)
3065 : : !write(std_out,*)'iwan,proj_x, proj_z',iwan,proj_x(:,iwan),proj_z(:,iwan)
3066 : : !end do
3067 : : !!END DEBUG
3068 : :
3069 : : !constants for linear combinations of ylm's
3070 : 0 : rs2=1._dp/sqrt(2._dp)
3071 : 0 : rs3=1._dp/sqrt(3._dp)
3072 : 0 : rs6=1._dp/sqrt(6._dp)
3073 : 0 : rs12=1._dp/sqrt(12._dp)
3074 : :
3075 : : !
3076 : : !mapping lm coefficients for real spherical harmonics
3077 : : !table 3.1 of Wannier90 user guide with real spherical harmonics in routine initylmr
3078 : : !s, py,pz,px, dxy,dyz,dz2,dxz,dx2-y2, fy(3x2-y2),fxyz,fyz2,fz3,fxz2,
3079 : : !fz(x2-y2),fx(x2-3y2)
3080 : : !note: check ordering of f orbitals, it might be wrong
3081 : :
3082 [ # # # # ]: 0 : tor(:,:)=0.d0
3083 : 0 : lm=0
3084 [ # # ]: 0 : do ll=0,lmax
3085 [ # # ]: 0 : do mm=-ll,ll
3086 : 0 : onem=(-1.d0)**mm
3087 : 0 : lm=lm+1
3088 [ # # ]: 0 : if(ll == 0) then
3089 : 0 : tor(lm,lm)=1.d0
3090 : : else
3091 : 0 : tor(lm,lm)=onem*1.d0
3092 : : end if
3093 : : end do !mm
3094 : : end do !ll
3095 : : !do lm=1,16
3096 : : !write(std_out,*)'tor lm=',lm,tor(:,lm)
3097 : : !end do
3098 : :
3099 : : !coefficients for basic wannier orbitals in Table 3.1 order
3100 [ # # # # : 0 : orb_lm(:,:,:)=0.d0
# # ]
3101 : : ii=0
3102 [ # # ]: 0 : do ll=0,lmax
3103 [ # # ]: 0 : do mr=1,2*ll+1
3104 : 0 : ii=ii+1
3105 [ # # ]: 0 : orb_lm(:,ll,mr)= tor(:,ii)
3106 : : ! write(std_out,*)'ii',ii,'orb_lm',orb_lm(:,ll,mr)
3107 : : end do
3108 : : end do
3109 : :
3110 : :
3111 : :
3112 : : !coefficients for linear combinations in table 3.2 order
3113 [ # # ]: 0 : if(lmax>=1) then
3114 : : ! s px
3115 [ # # ]: 0 : orb_lm(:,-1,1)=rs2*tor(:,1)+rs2*tor(:,4)
3116 [ # # ]: 0 : orb_lm(:,-1,2)=rs2*tor(:,1)-rs2*tor(:,4)
3117 : : ! s px py
3118 [ # # ]: 0 : orb_lm(:,-2,1)=rs3*tor(:,1)-rs6*tor(:,4)+rs2*tor(:,2)
3119 [ # # ]: 0 : orb_lm(:,-2,2)=rs3*tor(:,1)-rs6*tor(:,4)-rs2*tor(:,2)
3120 [ # # ]: 0 : orb_lm(:,-2,3)=rs3*tor(:,1)+2._dp*rs6*tor(:,4)
3121 : : ! s px py pz
3122 [ # # ]: 0 : orb_lm(:,-3,1)=half*(tor(:,1)+tor(:,4)+tor(:,2)+tor(:,3))
3123 [ # # ]: 0 : orb_lm(:,-3,2)=half*(tor(:,1)+tor(:,4)-tor(:,2)-tor(:,3))
3124 [ # # ]: 0 : orb_lm(:,-3,3)=half*(tor(:,1)-tor(:,4)+tor(:,2)-tor(:,3))
3125 [ # # ]: 0 : orb_lm(:,-3,4)=half*(tor(:,1)-tor(:,4)-tor(:,2)+tor(:,3))
3126 : : end if
3127 [ # # ]: 0 : if(lmax>=2) then
3128 : : ! s px py
3129 [ # # ]: 0 : orb_lm(:,-4,1)=rs3*tor(:,1)-rs6*tor(:,4)+rs2*tor(:,2)
3130 [ # # ]: 0 : orb_lm(:,-4,2)=rs3*tor(:,1)-rs6*tor(:,4)-rs2*tor(:,2)
3131 [ # # ]: 0 : orb_lm(:,-4,3)=rs3*tor(:,1)+2._dp*rs6*tor(:,4)
3132 : : ! pz dz2
3133 [ # # ]: 0 : orb_lm(:,-4,4)= rs2*tor(:,3)+rs2*tor(:,7)
3134 [ # # ]: 0 : orb_lm(:,-4,5)=-rs2*tor(:,3)+rs2*tor(:,7)
3135 : : ! s px dz2 dx2-y2
3136 [ # # ]: 0 : orb_lm(:,-5,1)=rs6*tor(:,1)-rs2*tor(:,4)-rs12*tor(:,7)+half*tor(:,9)
3137 [ # # ]: 0 : orb_lm(:,-5,2)=rs6*tor(:,1)+rs2*tor(:,4)-rs12*tor(:,7)+half*tor(:,9)
3138 : : ! s py dz2 dx2-y2
3139 [ # # ]: 0 : orb_lm(:,-5,3)=rs6*tor(:,1)-rs2*tor(:,2)-rs12*tor(:,7)-half*tor(:,9)
3140 [ # # ]: 0 : orb_lm(:,-5,4)=rs6*tor(:,1)+rs2*tor(:,2)-rs12*tor(:,7)-half*tor(:,9)
3141 : : ! s pz dz2
3142 [ # # ]: 0 : orb_lm(:,-5,5)=rs6*tor(:,1)-rs2*tor(:,3)+rs3*tor(:,7)
3143 [ # # ]: 0 : orb_lm(:,-5,6)=rs6*tor(:,1)+rs2*tor(:,3)+rs3*tor(:,7)
3144 : : end if
3145 : :
3146 : : !real wannier orbital coefficient array
3147 [ # # ]: 0 : do iwan=1,nwan
3148 [ # # ]: 0 : ylmr_fac(:,iwan)=orb_lm(:,proj_l(iwan),proj_m(iwan))
3149 : : end do
3150 : :
3151 : :
3152 : : !setup to rotate ylmr_fac to new axes if called for
3153 : : !skip if only s projetors are used
3154 [ # # ]: 0 : if ( lmax>0 ) then
3155 : : ! generate a set of nr=lmax2 random vectors
3156 : 0 : idum=123456
3157 [ # # ]: 0 : do ir=1,lmax2
3158 [ # # ]: 0 : do ii=1,3
3159 : 0 : r(ii,ir) = uniformrandom(idum)-0.5d0
3160 : : end do !ii
3161 : : end do !ir
3162 [ # # # # : 0 : ABI_MALLOC(nrm,(lmax2))
# # # # #
# # # ]
3163 [ # # ]: 0 : nrm(:)=sqrt(r(1,:)**2+r(2,:)**2+r(3,:)**2)**0.5
3164 : 0 : call initylmr(lmax+1,1,lmax2,nrm,1,r(:,:),ylmr_rr_save(:,:),dummy)
3165 [ # # # # ]: 0 : ylmr_rr(:,:)=ylmr_rr_save(:,:)
3166 [ # # ]: 0 : do ir=1,lmax2
3167 [ # # ]: 0 : ylmr_rr_save(ir,:)=ylmr_rr(:,ir)
3168 : : end do
3169 [ # # ]: 0 : ABI_FREE(nrm)
3170 : :
3171 [ # # # # ]: 0 : ylmr_rrinv(:,:)=0.d0
3172 [ # # ]: 0 : do ii=1,lmax2
3173 : 0 : ylmr_rrinv(ii,ii)=1.d0
3174 : : end do !ii
3175 : : ! calculate inverse of ylmr(ir,lm) matrix
3176 [ # # # # ]: 0 : ylmr_rrinv(:,:)=ylmr_rr_save(:,:)
3177 : 0 : call matrginv(ylmr_rrinv,lmax2,lmax2)
3178 : :
3179 : : ! check that r points are independent (ie., that matrix inversion wasn't too close to singular)
3180 [ # # # # : 0 : ylmr_rr=matmul(ylmr_rrinv,ylmr_rr_save)
# # # # #
# # # ]
3181 : 0 : test=0.d0
3182 [ # # ]: 0 : do ii=1,lmax2
3183 : 0 : ylmr_rr(ii,ii)=ylmr_rr(ii,ii)-1.d0
3184 [ # # ]: 0 : do jj=1,lmax2
3185 : 0 : test=max(abs(ylmr_rr(ii,jj)),test)
3186 : : end do !ii
3187 : : end do !jj
3188 [ # # ]: 0 : if(test>tol8) then
3189 : : write(msg, '(5a)' )&
3190 : 0 : ' matrix inversion error for wannier rotations',ch10,&
3191 : 0 : ' random vectors r(j,1:nr) are not all independent !! ',ch10,&
3192 : 0 : ' Action : re-seed uniformrandom or maybe just try again'
3193 : 0 : ABI_ERROR(msg)
3194 : : end if !test>tol8
3195 : :
3196 : : ! end of the preliminaries, now to the rotations of the wannier orbitals
3197 [ # # ]: 0 : do iwan=1,nwan
3198 : : ! don't bother for s orbitals
3199 [ # # ]: 0 : if(proj_l(iwan)==0) cycle
3200 : : ! check for default axes and cycle if found
3201 : : if(proj_z(1,iwan)==0.d0 .and. proj_z(2,iwan)==0.d0 .and.&
3202 : : & proj_z(3,iwan)== 1.d0 .and. proj_x(1,iwan)==1.d0 .and.&
3203 [ # # # # : 0 : & proj_x(2,iwan)==0.d0 .and. proj_x(3,iwan)==0.d0) cycle
# # # # #
# # # ]
3204 : :
3205 : : ! get the u matrix that rotates the reference frame
3206 : 0 : call rotmat(proj_x(:,iwan),proj_z(:,iwan),inversion_flag,umat)
3207 : : !
3208 : : ! find rotated r-vectors. Optional inversion
3209 : : ! operation is an extension of the wannier90 axis-setting options
3210 : : ! which only allow for proper axis rotations
3211 [ # # ]: 0 : if(inversion_flag==1) then
3212 [ # # # # : 0 : rp(:,:)= -matmul ( umat(:,:), r(:,:) )
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
3213 : : else
3214 [ # # # # : 0 : rp(:,:) = matmul ( umat(:,:) , r(:,:) )
# # # # #
# # # ]
3215 : : end if !inversion_flag
3216 : :
3217 : : ! get the ylm representation of the rotated vectors
3218 [ # # # # : 0 : ABI_MALLOC(nrm,(lmax2))
# # # # ]
3219 [ # # ]: 0 : nrm(:)=sqrt(rp(1,:)**2+rp(2,:)**2+rp(3,:)**2)**0.5
3220 : 0 : call initylmr(lmax+1,1,lmax2,nrm,1,rp(:,:),ylmr_rp(:,:),dummy)
3221 [ # # # # ]: 0 : ylmr_rr(:,:)=ylmr_rp(:,:)
3222 [ # # ]: 0 : do ir=1,lmax2
3223 [ # # ]: 0 : ylmr_rp(ir,:)=ylmr_rr(:,ir)
3224 : : end do
3225 [ # # ]: 0 : ABI_FREE(nrm)
3226 : : ! the matrix product sum(ir) ylmr_rrinv(lm,ir)*ylmr_rp(ir,lm') gives the
3227 : : ! the lmXlm matrix representation of the coordinate rotation
3228 : :
3229 [ # # # # : 0 : rot(:,:)=matmul(ylmr_rrinv(:,:),ylmr_rp(:,:))
# # # # #
# # # ]
3230 : : !
3231 : : ! now rotate the current wannier orbital
3232 [ # # # # : 0 : ylmrp(:)=matmul(rot(:,:),ylmr_fac(:,iwan))
# # ]
3233 [ # # ]: 0 : ylmr_fac(:,iwan)=ylmrp(:)
3234 : : end do !iwan
3235 : : end if !lmax>0
3236 : :
3237 : 0 : end subroutine mlwfovlp_ylmfar
3238 : : !!***
3239 : :
3240 : : !!****f* m_mlwfovlp/wan_from_abiwan
3241 : : !! NAME
3242 : : !! wan_from_abiwan
3243 : : !!
3244 : : !! FUNCTION
3245 : : !! Initialize a wan_t instance from the ABIWAN.nc netcf file
3246 : : !!
3247 : : !! INPUTS
3248 : : !!
3249 : : !! OUTPUT
3250 : : !!
3251 : : !! SOURCE
3252 : :
3253 : 0 : subroutine wan_from_abiwan(wan, abiwan_filepath, spin, nsppol, keep_umats, out_prefix, comm)
3254 : :
3255 : : !Arguments ------------------------------------
3256 : : class(wan_t),intent(out) :: wan
3257 : : character(len=*),intent(in) :: abiwan_filepath, out_prefix
3258 : : logical,intent(in) :: keep_umats
3259 : : integer,intent(in) :: spin, nsppol, comm
3260 : :
3261 : : !Local variables-------------------------------
3262 : : !scalars
3263 : : integer,parameter :: master = 0
3264 : : integer :: ncid, my_rank, ii, ir, ik, ib, jb, mb, nsppol_, mband, nwan, nkbz, ount, num_bands, nr_h, nextbands
3265 : : character(len=500) :: msg
3266 : : character(len=fnlen) :: out_path
3267 [ # # # # : 0 : type(crystal_t) :: cryst
# # # # #
# # # # #
# # # # #
# ]
3268 : : complex(dp) :: ctmp
3269 : : !arrays
3270 : : integer :: kptrlatt(3,3)
3271 : 0 : integer,allocatable :: int_1d(:), int_2d(:,:) !, shiftk(:,:)
3272 [ # # ]: 0 : real(dp),allocatable :: u_mat(:,:,:,:), u_mat_opt(:,:,:,:), et_opt(:,:)
3273 : 0 : complex(dp),allocatable :: chs(:,:,:), chw(:,:,:)
3274 : : !************************************************************************
3275 : :
3276 : 0 : my_rank = xmpi_comm_rank(comm)
3277 : :
3278 : : !if (my_rank == master) then
3279 : 0 : wan%spin = spin
3280 [ # # ]: 0 : NCF_CHECK(nctk_open_read(ncid, abiwan_filepath, comm))
3281 : :
3282 : : ! Get dimensions.
3283 [ # # ]: 0 : NCF_CHECK(nctk_get_dim(ncid, "number_of_spins", nsppol_))
3284 [ # # ]: 0 : ABI_CHECK_IEQ(nsppol, nsppol_, "Inconsistent number of spins")
3285 : :
3286 : 0 : call cryst%ncread(ncid)
3287 : :
3288 : : ! NB: mband is the value of nband and not the number of bands for Wannier that is called num_bands!
3289 [ # # ]: 0 : NCF_CHECK(nctk_get_dim(ncid, "max_number_of_states", mband))
3290 [ # # ]: 0 : NCF_CHECK(nctk_get_dim(ncid, "number_of_kpoints", nkbz))
3291 [ # # ]: 0 : NCF_CHECK(nctk_get_dim(ncid, "nrpts", nr_h))
3292 [ # # ]: 0 : NCF_CHECK(nctk_get_dim(ncid, "mwan", wan%max_nwan))
3293 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("nwan"), nwan, start=[spin]))
# # ]
3294 : 0 : wan%nkbz = nkbz; wan%nwan = nwan; wan%nr_h = nr_h
3295 : :
3296 : : ! Read variables for this spin.
3297 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("num_bands"), num_bands, start=[spin]))
# # ]
3298 : 0 : wan%num_bands = num_bands
3299 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "spread"), wan%spread, start=[1,spin]))
# # ]
3300 : :
3301 [ # # # # : 0 : ABI_MALLOC(wan%kbz, (3, nkbz))
# # # # #
# # # #
# ]
3302 [ # # ]: 0 : NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "reduced_coordinates_of_kpoints"), wan%kbz))
3303 : :
3304 [ # # # # : 0 : ABI_MALLOC(wan%r_h, (3, nr_h))
# # # # #
# # # #
# ]
3305 [ # # # # : 0 : ABI_MALLOC(wan%ndegen_h, (nr_h))
# # # # #
# # # #
# ]
3306 [ # # ]: 0 : NCF_CHECK(nf90_get_var(ncid, vid("irvec"), wan%r_h))
3307 [ # # ]: 0 : NCF_CHECK(nf90_get_var(ncid, vid("ndegen"), wan%ndegen_h))
3308 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("have_disentangled_spin"), ii, start=[spin]))
# # ]
3309 : :
3310 [ # # # # : 0 : ABI_MALLOC(wan%exclude_bands, (mband))
# # # # #
# # # #
# ]
3311 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("exclude_bands"), wan%exclude_bands, start=[1,spin]))
# # ]
3312 : :
3313 : 0 : wan%have_disentangled = (ii /= 0)
3314 : :
3315 : : ! Read U matrices using real arrays.
3316 : : ! TODO: This should be tested more carefully, especially when we are excluding bands.
3317 [ # # # # : 0 : ABI_MALLOC(u_mat, (2, nwan, nwan, nkbz))
# # # # #
# # # # #
# # # # #
# ]
3318 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("U_matrix"), u_mat, start=[1,1,1,1,spin], count=[2, nwan, nwan, nkbz, 1]))
# # # # #
# ]
3319 [ # # # # : 0 : ABI_MALLOC(u_mat_opt, (2, num_bands, nwan, nkbz))
# # # # #
# # # # #
# # # # #
# ]
3320 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("U_matrix_opt"), u_mat_opt, start=[1,1,1,1,spin], count=[2, num_bands, nwan, nkbz, 1]))
# # # # #
# ]
3321 : :
3322 : : ! Copy data: real --> complex
3323 [ # # # # : 0 : ABI_MALLOC(wan%u_mat, (num_bands, nwan, nkbz))
# # # # #
# # # # #
# # # # #
# # # ]
3324 [ # # # # : 0 : ABI_MALLOC(wan%u_mat_opt, (nwan, nwan, nkbz))
# # # # #
# # # # #
# # # # #
# # # ]
3325 [ # # # # : 0 : wan%u_mat = u_mat(1,:,:,:) + j_dpc * u_mat(2,:,:,:)
# # # # #
# # # # #
# # ]
3326 [ # # # # : 0 : wan%u_mat_opt = u_mat_opt(1,:,:,:) + j_dpc * u_mat_opt(2,:,:,:)
# # # # #
# # # # #
# # ]
3327 : :
3328 [ # # ]: 0 : ABI_FREE(u_mat)
3329 [ # # ]: 0 : ABI_FREE(u_mat_opt)
3330 : :
3331 [ # # # # : 0 : ABI_MALLOC(wan%centres, (3, nwan))
# # # # #
# # # #
# ]
3332 [ # # # # : 0 : ABI_MALLOC(wan%spreads, (nwan))
# # # # #
# # # #
# ]
3333 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("wann_centres"), wan%centres, start=[1,1,spin], count=[3, nwan, 1]))
# # # # #
# ]
3334 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("wann_spreads"), wan%spreads, start=[1,spin], count=[nwan]))
# # # # #
# ]
3335 : :
3336 [ # # # # : 0 : ABI_MALLOC(int_1d, (num_bands))
# # # # #
# # # #
# ]
3337 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("band_in_int"), int_1d, start=[1,spin], count=[num_bands, 1]))
# # # # #
# ]
3338 [ # # # # : 0 : ABI_MALLOC(wan%band_in, (num_bands))
# # # # #
# # # #
# ]
3339 [ # # # # : 0 : wan%band_in = (int_1d /= 0)
# # # # ]
3340 [ # # ]: 0 : ABI_FREE(int_1d)
3341 : :
3342 [ # # # # : 0 : ABI_MALLOC(int_2d, (num_bands, wan%nkbz))
# # # # #
# # # # #
# # # # ]
3343 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("lwindow_int"), int_2d, start=[1,1,spin], count=[num_bands, nkbz, 1]))
# # # # #
# ]
3344 [ # # # # : 0 : ABI_MALLOC(wan%lwindow, (wan%num_bands, wan%nkbz))
# # # # #
# # # # #
# # # # ]
3345 [ # # # # : 0 : wan%lwindow = (int_2d /= 0)
# # # # #
# # # ]
3346 [ # # ]: 0 : ABI_FREE(int_2d)
3347 : :
3348 [ # # ]: 0 : NCF_CHECK(nf90_get_var(ncid, vid("kptrlatt"), kptrlatt))
3349 [ # # ]: 0 : ABI_CHECK(isdiagmat(kptrlatt), "kptrlatt should be diagonal! Please use nkgpt with one shift")
3350 [ # # ]: 0 : wan%ngkpt = get_diag(kptrlatt)
3351 : : !NCF_CHECK(nctk_get_dim(ncid, "nshiftk", wan%nshiftk))
3352 : : !if nshiftk
3353 : :
3354 : : ! Read all KS eigenvalues and trasfer data to %eigs_w (note mband here)
3355 [ # # # # : 0 : ABI_MALLOC(wan%all_eigens, (mband, nkbz))
# # # # #
# # # # #
# # # # ]
3356 [ # # # # : 0 : NCF_CHECK(nf90_get_var(ncid, vid("eigenvalues"), wan%all_eigens, start=[1,1,spin]))
# # ]
3357 : :
3358 [ # # ]: 0 : NCF_CHECK(nf90_close(ncid))
3359 : : !end if ! master
3360 : :
3361 : : ! Compute dimwin, winstart, bmin and bmax from lwindow.
3362 [ # # # # : 0 : ABI_ICALLOC(wan%dimwin, (nkbz))
# # # # #
# # # # #
# # ]
3363 [ # # # # : 0 : ABI_ICALLOC(wan%winstart, (nkbz))
# # # # #
# # # ]
3364 : :
3365 : 0 : wan%bmin = huge(1); wan%bmax = -1
3366 [ # # ]: 0 : do ik=1,nkbz
3367 [ # # ]: 0 : do ib=1,wan%num_bands
3368 [ # # ]: 0 : if (wan%lwindow(ib, ik)) then
3369 : 0 : wan%dimwin(ik) = wan%dimwin(ik) + 1
3370 [ # # ]: 0 : if (wan%winstart(ik) == 0) wan%winstart(ik) = ib
3371 : 0 : wan%bmin = min(wan%bmin, ib)
3372 : 0 : wan%bmax = max(wan%bmax, ib)
3373 : : end if
3374 : : end do
3375 : : end do
3376 : :
3377 : 0 : call wan%krank%from_kptrlatt(nkbz, wan%kbz, kptrlatt, compute_invrank=.True.)
3378 : :
3379 [ # # # # : 0 : ABI_MALLOC(wan%rmod_h, (wan%nr_h))
# # # # #
# # # #
# ]
3380 [ # # ]: 0 : do ir=1,wan%nr_h
3381 [ # # # # : 0 : wan%rmod_h(ir) = sqrt(dot_product(wan%r_h(:,ir), matmul(cryst%rmet, wan%r_h(:,ir))))
# # # # #
# ]
3382 : : end do
3383 : :
3384 : : ! Get total rotation matrix: the product of the optimal subspace x the rotation among the nwan Wannier functions.
3385 [ # # ]: 0 : ii = maxval(wan%dimwin)
3386 [ # # # # : 0 : ABI_CALLOC(wan%u_k, (ii, nwan, nkbz))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
3387 [ # # ]: 0 : do ik=1,nkbz
3388 [ # # # # : 0 : wan%u_k(1:wan%dimwin(ik), 1:nwan, ik) = matmul(wan%u_mat_opt(1:wan%dimwin(ik), :, ik), wan%u_mat(:, 1:nwan, ik))
# # # # #
# # # # #
# # # # #
# ]
3389 : : end do
3390 : :
3391 : 0 : wan%keep_umats = keep_umats
3392 : :
3393 [ # # ]: 0 : if (.not. keep_umats) then
3394 [ # # ]: 0 : ABI_FREE(wan%u_mat)
3395 [ # # ]: 0 : ABI_FREE(wan%u_mat_opt)
3396 : : end if
3397 : :
3398 : : ! ====================================================
3399 : : ! Build the Hamiltonian in the Wannier representation
3400 : : ! ====================================================
3401 : : !call wan%get_window_eig(et_opt)
3402 [ # # # # ]: 0 : nextbands = count(wan%exclude_bands /= 0)
3403 : : !REAL(KIND = DP) :: et_opt(nbndep, nks)
3404 : : ! KS eigenvalues within the outer window in the first dimwin(ik) entries
3405 : 0 : ii = wan%num_bands ! TODO: Check
3406 [ # # # # : 0 : ABI_MALLOC(et_opt, (ii ,nkbz))
# # # # #
# # # # #
# # ]
3407 : :
3408 : : !print *, "nextbands", nextbands; print *, "exclude_bands:", wan%exclude_bands
3409 : : !print *, "band_in:", wan%band_in; print *, "lwindow:", wan%lwindow
3410 : :
3411 [ # # ]: 0 : if (nextbands /= 0) then
3412 [ # # ]: 0 : do ik=1,nkbz
3413 : : jb = 0; mb = 0
3414 [ # # ]: 0 : do ib=1,wan%num_bands
3415 : : !if (wan%exclude_bands(ib) /= 0) cycle
3416 [ # # ]: 0 : if (.not. wan%band_in(ib)) cycle
3417 : 0 : jb = jb + 1
3418 [ # # ]: 0 : if (wan%lwindow(jb, ik)) then
3419 : 0 : mb = mb + 1; et_opt(mb, ik) = wan%all_eigens(ib, ik)
3420 : : end if
3421 : : end do
3422 : : end do
3423 : :
3424 : : else
3425 [ # # ]: 0 : do ik=1,nkbz
3426 : 0 : mb = 0
3427 [ # # ]: 0 : do ib=1,wan%dimwin(ik)
3428 [ # # ]: 0 : if (wan%lwindow(ib, ik)) then
3429 : 0 : mb = mb + 1; et_opt(mb, ik) = wan%all_eigens(ib, ik)
3430 : : end if
3431 : : end do
3432 : : end do
3433 : : end if
3434 : :
3435 [ # # # # : 0 : ABI_CALLOC(chs, (nwan, nwan, nkbz))
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
3436 : :
3437 [ # # ]: 0 : do ik=1,nkbz
3438 [ # # ]: 0 : do jb=1,nwan
3439 [ # # ]: 0 : do ib=1,jb
3440 : 0 : ctmp = czero
3441 [ # # ]: 0 : do mb=1,wan%dimwin(ik)
3442 : 0 : ctmp = ctmp + conjg(wan%u_k(mb, ib, ik)) * et_opt(mb, ik) * wan%u_k(mb, jb, ik)
3443 : : end do
3444 : 0 : chs(ib, jb, ik) = ctmp
3445 : 0 : chs(jb, ib, ik) = conjg(ctmp)
3446 : : end do
3447 : : end do
3448 : : end do ! ik
3449 [ # # ]: 0 : ABI_FREE(et_opt)
3450 : :
3451 [ # # # # : 0 : ABI_CALLOC(chw, (nwan, nwan, nr_h))
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
3452 [ # # ]: 0 : do ir=1,nr_h
3453 [ # # ]: 0 : do ik=1,nkbz
3454 [ # # # # : 0 : chw(:,:,ir) = chw(:,:,ir) + chs(:,:,ik) * exp(-j_dpc * two_pi * dot_product(wan%kbz(:, ik), wan%r_h(:, ir))) / dble(nkbz)
# # ]
3455 : : end do
3456 : : end do
3457 [ # # ]: 0 : ABI_FREE(chs)
3458 : :
3459 : : ! Now rearrange the data to have R_e in the first dimension.
3460 [ # # # # : 0 : ABI_CALLOC(wan%hwan_r, (nr_h, nwan, nwan))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
3461 [ # # ]: 0 : do ir=1,nr_h
3462 [ # # # # ]: 0 : wan%hwan_r(ir,:,:) = chw(:,:,ir)
3463 : : end do
3464 [ # # ]: 0 : ABI_FREE(chw)
3465 : :
3466 : : ! Write spatial decay to file.
3467 [ # # # # ]: 0 : if (my_rank == master .and. len_trim(out_prefix) > 0) then
3468 [ # # ]: 0 : out_path = strcat(out_prefix, "_spin", itoa(spin), "_HRWAN.txt")
3469 [ # # ]: 0 : if (open_file(out_path, msg, newunit=ount, form="formatted", action="write", status='unknown') /= 0) then
3470 : 0 : ABI_ERROR(msg)
3471 : : end if
3472 : 0 : write(ount, "(a)")"# Decay of Hamiltonian in the Wannier representation"
3473 : 0 : write(ount, "(a)")"# |R| [Bohr] Max_{m,n} |H(R,m,n)| [Ha]"
3474 [ # # ]: 0 : do ir=1,nr_h
3475 [ # # # # : 0 : write(ount, *) wan%rmod_h(ir), maxval(abs(wan%hwan_r(ir,:,:)))
# # # # #
# # # ]
3476 : : end do
3477 : 0 : close(ount)
3478 : : end if
3479 : :
3480 [ # # # # : 0 : call cryst%free()
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
3481 : :
3482 : : contains
3483 : 0 : integer function vid(var_name)
3484 : : character(len=*),intent(in) :: var_name
3485 : 0 : vid = nctk_idname(ncid, var_name)
3486 : : end function vid
3487 : :
3488 : : end subroutine wan_from_abiwan
3489 : : !!***
3490 : :
3491 : : !!****f* m_mlwfovlp/wan_print
3492 : : !! NAME
3493 : : !! wan_print
3494 : : !!
3495 : : !! FUNCTION
3496 : : !!
3497 : : !! SOURCE
3498 : :
3499 [ # # ]: 0 : subroutine wan_print(wan, units)
3500 : :
3501 : : !Arguments ------------------------------------
3502 : : class(wan_t),intent(in) :: wan
3503 : : integer,intent(in) :: units(:)
3504 : :
3505 : : !Local variables-------------------------------
3506 : : type(yamldoc_t) :: ydoc
3507 : : !************************************************************************
3508 : :
3509 : 0 : ydoc = yamldoc_open("WANNIER_PARAMS")
3510 : :
3511 : : !call ydoc%add_string("method", "Gaussian")
3512 : : call ydoc%add_ints("spin, nwan, num_bands, bmin, bmax, nkbz, nr_h, nr_e, nr_p", &
3513 [ # # ]: 0 : [wan%spin, wan%nwan, wan%num_bands, wan%bmin, wan%bmax, wan%nkbz, wan%nr_h, wan%nr_e, wan%nr_p])
3514 : : !call ydoc%add_reals("nelect, wan_mesh_step_eV", &
3515 : : ! [wan%nelect, wan%step * Ha_eV])
3516 : : !call ydoc%add_real("", efermi * Ha_eV)
3517 : :
3518 : : ! Write header in Yaml format but prepend # so that one can still use tools such as gnuplot or xmgrace.
3519 : 0 : call ydoc%write_units_and_free(units)
3520 : :
3521 : 0 : end subroutine wan_print
3522 : : !!***
3523 : :
3524 : : !!****f* m_mlwfovlp/wan_interp_ham
3525 : : !! NAME
3526 : : !! wan_interp_ham
3527 : : !!
3528 : : !! FUNCTION
3529 : : !! Interpolate the Hamiltonian at an arbitrary k-point and return the rotation
3530 : : !! matrix. If vcart is present, also return diagonal Cartesian group velocities
3531 : : !! obtained from the analytic derivative of the real-space Hamiltonian.
3532 : : !! Velocities are in atomic units.
3533 : : !!
3534 : : !! TODO: This routine presently implements the legacy Wannier90 interpolation
3535 : : !! obtained with use_ws_distance=.false. Modern Wannier90 versions enable
3536 : : !! use_ws_distance by default and use pair-dependent translated lattice vectors
3537 : : !! and degeneracies from w90_ws_distance:ws_translate_dist (irdist_ws and
3538 : : !! wdist_ndeg). For an Al test, the legacy and default Wannier90 interpolations
3539 : : !! differed by about 0.05 eV on average and up to 0.26 eV along a k-path.
3540 : : !!
3541 : : !! The current Wannier90 library interface does not return these arrays and
3542 : : !! deallocates its internal parameters before wannier_run returns. A possible
3543 : : !! implementation is to request write_hr=.true., read the resulting *_hr.dat
3544 : : !! and *_wsvec.dat files after wannier_run, and store the Hamiltonian and
3545 : : !! pair-dependent WS data in ABIWAN.nc for use here and by AbiPy.
3546 : : !!
3547 : : !! INPUTS
3548 : : !! cryst: Crystal structure providing the dimensional primitive vectors.
3549 : : !! kpt: Reduced coordinates of the interpolation point.
3550 : : !!
3551 : : !! OUTPUTS
3552 : : !! uk_wan: Eigenvectors of the interpolated Hamiltonian, stored by columns.
3553 : : !! eigens: Interpolated eigenvalues in Hartree.
3554 : : !! vcart: Optional diagonal Cartesian group velocities in atomic units.
3555 : : !! Individual values inside an exactly degenerate subspace depend on the
3556 : : !! eigenvectors selected by the diagonalization.
3557 : : !!
3558 : : !! SOURCE
3559 : :
3560 : 0 : subroutine wan_interp_ham(wan, cryst, kpt, uk_wan, eigens, vcart)
3561 : :
3562 : : !Arguments ------------------------------------
3563 : : class(wan_t),intent(in) :: wan
3564 : : class(crystal_t),intent(in) :: cryst
3565 : : real(dp),intent(in) :: kpt(3)
3566 : : real(dp),intent(out) :: eigens(wan%nwan)
3567 : : complex(dp),intent(out) :: uk_wan(wan%nwan, wan%nwan)
3568 : : real(dp),optional,intent(out) :: vcart(3, wan%nwan)
3569 : :
3570 : : !Local variables-------------------------------
3571 : : integer :: ir, idir, ib
3572 : 0 : real(dp) :: rcart(3,wan%nr_h)
3573 : 0 : complex(dp) :: eikr(wan%nr_h),deikr(wan%nr_h), dham(wan%nwan, wan%nwan), vmat(wan%nwan, wan%nwan)
3574 : : !************************************************************************
3575 : :
3576 [ # # ]: 0 : do ir=1,wan%nr_h
3577 [ # # ]: 0 : eikr(ir) = exp(j_dpc * two_pi * dot_product(kpt, wan%r_h(:, ir))) / wan%ndegen_h(ir)
3578 : : end do
3579 : :
3580 : : ! H_ij(k) = sum_R e^{+ik.R} * H_ij(R)
3581 : 0 : call ZGEMV("T", wan%nr_h, wan%nwan**2, cone, wan%hwan_r, wan%nr_h, eikr, 1, czero, uk_wan, 1)
3582 : :
3583 : : ! Hermitianize and diagonalize. xheev returns eigenvectors as columns.
3584 [ # # # # : 0 : uk_wan = half * (uk_wan + transpose(conjg(uk_wan)))
# # # # #
# ]
3585 : 0 : call xheev("V", "U", wan%nwan, uk_wan, eigens)
3586 : :
3587 [ # # ]: 0 : if (present(vcart)) then
3588 [ # # ]: 0 : do ir=1,wan%nr_h
3589 [ # # # # : 0 : rcart(:,ir) = matmul(cryst%rprimd, real(wan%r_h(:,ir), kind=dp))
# # # # #
# ]
3590 : : end do
3591 [ # # ]: 0 : do idir=1,3
3592 [ # # ]: 0 : do ir=1,wan%nr_h
3593 : 0 : deikr(ir) = j_dpc * rcart(idir,ir) * eikr(ir)
3594 : : end do
3595 : 0 : call ZGEMV("T", wan%nr_h, wan%nwan**2, cone, wan%hwan_r, wan%nr_h, deikr, 1, czero, dham, 1)
3596 [ # # # # : 0 : dham = half * (dham + transpose(conjg(dham)))
# # # # ]
3597 [ # # # # : 0 : vmat = matmul(transpose(conjg(uk_wan)), matmul(dham, uk_wan))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
3598 [ # # ]: 0 : do ib=1,wan%nwan
3599 : 0 : vcart(idir,ib) = real(vmat(ib,ib), kind=dp)
3600 : : end do
3601 : : end do
3602 : : end if
3603 : :
3604 : 0 : end subroutine wan_interp_ham
3605 : : !!***
3606 : :
3607 : : !!****f* m_mlwfovlp/wan_free
3608 : : !! NAME
3609 : : !! wan_free
3610 : : !!
3611 : : !! FUNCTION
3612 : : !! Free dynamic memory.
3613 : : !!
3614 : : !! SOURCE
3615 : :
3616 : 32 : subroutine wan_free(wan)
3617 : :
3618 : : !Arguments ------------------------------------
3619 : : class(wan_t),intent(inout) :: wan
3620 : : !************************************************************************
3621 : :
3622 : : ! integer
3623 [ - + ]: 32 : ABI_SFREE(wan%dimwin)
3624 [ - + ]: 32 : ABI_SFREE(wan%winstart)
3625 [ - + ]: 32 : ABI_SFREE(wan%exclude_bands)
3626 [ - + ]: 32 : ABI_SFREE(wan%r_h)
3627 [ - + ]: 32 : ABI_SFREE(wan%r_e)
3628 [ - + ]: 32 : ABI_SFREE(wan%r_p)
3629 : :
3630 : : ! real
3631 [ - + ]: 32 : ABI_SFREE(wan%ndegen_h)
3632 [ - + ]: 32 : ABI_SFREE(wan%ndegen_e)
3633 [ - + ]: 32 : ABI_SFREE(wan%ndegen_p)
3634 [ - + ]: 32 : ABI_SFREE(wan%rmod_h)
3635 [ - + ]: 32 : ABI_SFREE(wan%rmod_e)
3636 [ - + ]: 32 : ABI_SFREE(wan%rmod_p)
3637 [ - + ]: 32 : ABI_SFREE(wan%all_eigens)
3638 [ - + ]: 32 : ABI_SFREE(wan%centres)
3639 [ - + ]: 32 : ABI_SFREE(wan%spreads)
3640 [ - + ]: 32 : ABI_SFREE(wan%kbz)
3641 [ - + ]: 32 : ABI_SFREE(wan%band_in)
3642 [ - + ]: 32 : ABI_SFREE(wan%lwindow)
3643 : :
3644 : : ! Complex
3645 [ - + ]: 32 : ABI_SFREE(wan%u_mat)
3646 [ - + ]: 32 : ABI_SFREE(wan%u_mat_opt)
3647 [ - + ]: 32 : ABI_SFREE(wan%u_k)
3648 [ - + ]: 32 : ABI_SFREE(wan%hwan_r)
3649 [ - + ]: 32 : ABI_SFREE(wan%grpe_wwp)
3650 : :
3651 : 32 : call wan%krank%free()
3652 : :
3653 : 32 : end subroutine wan_free
3654 : : !!***
3655 : :
3656 : : !!****f* m_mlwfovlp/wan_setup_eph_ws_kq
3657 : : !! NAME
3658 : : !! wan_setup_eph_ws_kq
3659 : : !!
3660 : : !! FUNCTION
3661 : : !! Prepare the interpolation of the e-ph matrix elements.
3662 : : !!
3663 : : !! SOURCE
3664 : :
3665 : 0 : subroutine wan_setup_eph_ws_kq(wan, cryst, shiftk, kptrlatt, qptrlatt, my_pert_start, my_npert, pert_comm)
3666 : :
3667 : : !Arguments ------------------------------------
3668 : : class(wan_t),intent(inout) :: wan
3669 : : type(crystal_t),intent(in) :: cryst
3670 : : real(dp),intent(in) :: shiftk(3)
3671 : : integer,intent(in) :: kptrlatt(3,3), qptrlatt(3,3), my_pert_start, my_npert
3672 : : type(xcomm_t),target,intent(in) :: pert_comm
3673 : :
3674 : : !Local variables-------------------------------
3675 : : integer,parameter :: lmax(3) = [2,2,2]
3676 : : real(dp),parameter :: center(3) = zero
3677 : : !************************************************************************
3678 : :
3679 : : ABI_UNUSED(shiftk)
3680 : :
3681 : : ! See Appendix A of Phys. Rev. Research 3, 043022 for possible improvements.
3682 [ # # ]: 0 : if (.not. allocated(wan%r_h)) then
3683 [ # # # # ]: 0 : call wigner_seitz(center, lmax, kptrlatt, cryst%rmet, wan%nr_h, wan%r_h, wan%ndegen_h, wan%rmod_h)
3684 : : end if
3685 : :
3686 [ # # ]: 0 : if (.not. allocated(wan%r_e)) then
3687 [ # # # # ]: 0 : call wigner_seitz(center, lmax, kptrlatt, cryst%rmet, wan%nr_e, wan%r_e, wan%ndegen_e, wan%rmod_e)
3688 : : end if
3689 : :
3690 [ # # ]: 0 : if (.not. allocated(wan%r_p)) then
3691 [ # # # # ]: 0 : call wigner_seitz(center, lmax, qptrlatt, cryst%rmet, wan%nr_p, wan%r_p, wan%ndegen_p, wan%rmod_p)
3692 : : end if
3693 : :
3694 [ # # ]: 0 : if (wan%my_pert_start == -1) then
3695 : 0 : wan%my_pert_start = my_pert_start; wan%my_npert = my_npert; wan%pert_comm => pert_comm
3696 : : else
3697 [ # # ]: 0 : ABI_CHECK_IEQ(wan%my_pert_start, my_pert_start, "different values for my_pert_start")
3698 [ # # ]: 0 : ABI_CHECK_IEQ(wan%my_npert, my_npert, "different values for my_npert")
3699 [ # # ]: 0 : ABI_CHECK(associated(wan%pert_comm), "wan%per_comm is not associated!")
3700 [ # # ]: 0 : ABI_CHECK_IEQ(wan%pert_comm%value, pert_comm%value, "different values for pert_comm%value")
3701 : : end if
3702 : :
3703 : : ! Allocate g in the Wannier representation.
3704 [ # # # # : 0 : ABI_CALLOC(wan%grpe_wwp, (wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, my_npert))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
3705 : :
3706 : 0 : end subroutine wan_setup_eph_ws_kq
3707 : : !!***
3708 : :
3709 : : !!****f* m_mlwfovlp/wan_interp_eph_manyq
3710 : : !! NAME
3711 : : !! wan_interp_eph_manyq
3712 : : !!
3713 : : !! FUNCTION
3714 : : !! Interpolate the e-ph matrix elements for one k-point and nq q-points.
3715 : : !! Returns matrix elements in the atomic-representation and, optionally, the
3716 : : !! eigenvalues obtained while diagonalizing the interpolated Hamiltonians.
3717 : : !!
3718 : : !! SOURCE
3719 : :
3720 : 0 : subroutine wan_interp_eph_manyq(wan, cryst, nq, qpts, kpt, g_atm, out_eigens_k, out_eigens_kq)
3721 : :
3722 : : !Arguments ------------------------------------
3723 : : class(wan_t),intent(in) :: wan
3724 : : class(crystal_t),intent(in) :: cryst
3725 : : integer,intent(in) :: nq
3726 : : real(dp),intent(in) :: qpts(3,nq), kpt(3)
3727 : : complex(dp),intent(out) :: g_atm(wan%nwan, wan%nwan, wan%my_npert, nq)
3728 : : real(dp),optional,intent(out) :: out_eigens_k(wan%nwan), out_eigens_kq(wan%nwan,nq)
3729 : :
3730 : : !Local variables-------------------------------
3731 : : integer :: ir, nr_e, nr_p, nwan, iq, my_npert, ipc, ncols_e, ncols_w
3732 : : !arrays
3733 : 0 : real(dp) :: kq(3), eigens_k(wan%nwan), eigens_kq(wan%nwan)
3734 : 0 : complex(dp),allocatable :: eikr(:), eiqr(:), u_k(:,:), u_kq(:,:), cbuf_e(:,:,:,:), cbuf_w(:,:,:), cmat_w(:,:)
3735 : : !************************************************************************
3736 : :
3737 : : ! TODO: Handle long-range part.
3738 : 0 : nr_p = wan%nr_p; nr_e = wan%nr_e; nwan = wan%nwan; my_npert = wan%my_npert
3739 : :
3740 [ # # # # : 0 : ABI_MALLOC(eikr, (nr_e))
# # # # #
# # # ]
3741 [ # # # # : 0 : ABI_MALLOC(eiqr, (nr_p))
# # # # #
# # # ]
3742 [ # # # # : 0 : ABI_MALLOC(u_k, (nwan, nwan))
# # # # #
# # # # #
# # ]
3743 [ # # # # : 0 : ABI_MALLOC(u_kq, (nwan, nwan))
# # # # #
# # # ]
3744 [ # # # # : 0 : ABI_MALLOC(cmat_w, (nwan, nwan))
# # # # #
# # # ]
3745 : :
3746 [ # # ]: 0 : do ir=1,nr_e
3747 [ # # ]: 0 : eikr(ir) = exp(+j_dpc * two_pi * dot_product(kpt, wan%r_e(:, ir))) / wan%ndegen_e(ir)
3748 : : end do
3749 : 0 : call wan%interp_ham(cryst, kpt, u_k, eigens_k)
3750 [ # # # # ]: 0 : if (present(out_eigens_k)) out_eigens_k = eigens_k
3751 : :
3752 : : ! grpe_wwp has shape: (nr_p, nr_e, nwan, nwan, my_npert))
3753 : 0 : ncols_e = nr_e * nwan **2 * my_npert
3754 [ # # # # : 0 : ABI_MALLOC(cbuf_e, (nr_e, nwan, nwan, my_npert))
# # # # #
# # # # #
# # # # #
# # # #
# ]
3755 : :
3756 : 0 : ncols_w = nwan ** 2 * my_npert
3757 [ # # # # : 0 : ABI_MALLOC(cbuf_w, (nwan, nwan, my_npert))
# # # # #
# # # # #
# # # # #
# ]
3758 : :
3759 [ # # ]: 0 : do iq=1,nq
3760 [ # # ]: 0 : kq = kpt + qpts(:,iq)
3761 : 0 : call wan%interp_ham(cryst, kq, u_kq, eigens_kq)
3762 [ # # # # ]: 0 : if (present(out_eigens_kq)) out_eigens_kq(:,iq) = eigens_kq
3763 [ # # ]: 0 : do ir=1,nr_p
3764 [ # # ]: 0 : eiqr(ir) = exp(+j_dpc * two_pi * dot_product(qpts(:,iq), wan%r_p(:, ir))) / wan%ndegen_p(ir)
3765 : : end do
3766 : :
3767 : : ! Transform along r_p
3768 : : ! [Eqn. 22 of PRB 76, 165108 (2007)]
3769 : : ! g~(R_e,q') = 1/ndegen(R_p) sum_R_p e^{iq'R_p} g(R_e,R_p)
3770 : 0 : call ZGEMV("T", nr_p, ncols_e, cone, wan%grpe_wwp, nr_p, eiqr, 1, czero, cbuf_e, 1)
3771 : :
3772 : : ! Transfor along r_e
3773 : : ! [Eqn. 22 of PRB 76, 165108 (2007)]
3774 : : ! g~(k',q') = 1/ndegen(R_e) sum_R_e e^{ik'R_e} g(R_e,q')
3775 : 0 : call ZGEMV("T", nr_e, ncols_w, cone, cbuf_e, nr_e, eikr, 1, czero, cbuf_w, 1)
3776 : :
3777 : : ! Go to Bloch space.
3778 : : ! [Eqn. 22 of PRB 76, 165108 (2007)]
3779 : : ! g(k',q') = U(k'+q') * g~(k',q') * U(k')^\dagger
3780 : : !
3781 : : ! RM - this is what is calculated
3782 : : ! g(k',q') = U(k'+q')^\dagger * g~(k',q') * U(k')
3783 : :
3784 : : ! the two zgemm calls perform the following operations:
3785 : : ! epmatf = [ cufkq * epmatf ] * cufkk^\dagger
3786 : :
3787 [ # # ]: 0 : do ipc=1,my_npert
3788 : 0 : call ZGEMM('N', 'N', nwan, nwan, nwan, cone, u_kq, nwan, cbuf_w(:,:,ipc), nwan, czero, cmat_w, nwan)
3789 : 0 : call ZGEMM('N', 'C', nwan, nwan, nwan, cone, cmat_w, nwan, u_k, nwan, czero, g_atm(:,:,ipc,iq), nwan)
3790 : : end do
3791 : : end do ! iq
3792 : :
3793 [ # # ]: 0 : ABI_FREE(cbuf_e)
3794 [ # # ]: 0 : ABI_FREE(cbuf_w)
3795 [ # # ]: 0 : ABI_FREE(eikr)
3796 [ # # ]: 0 : ABI_FREE(eiqr)
3797 [ # # ]: 0 : ABI_FREE(u_k)
3798 [ # # ]: 0 : ABI_FREE(u_kq)
3799 [ # # ]: 0 : ABI_FREE(cmat_w)
3800 : :
3801 [ # # ]: 0 : end subroutine wan_interp_eph_manyq
3802 : : !!***
3803 : :
3804 : : !!****f* m_mlwfovlp/wan_interp_eph_manyk
3805 : : !! NAME
3806 : : !! wan_interp_eph_manyk
3807 : : !!
3808 : : !! FUNCTION
3809 : : !! Interpolate the e-ph matrix elements for one q-point and nk k-points.
3810 : : !! The q-dependent R_p -> q Fourier transform is performed only once, then
3811 : : !! reused for all k-points. Work arrays are allocated once per k batch.
3812 : : !! Results are returned in the atomic-perturbation representation.
3813 : : !!
3814 : : !! SOURCE
3815 : :
3816 : 0 : subroutine wan_interp_eph_manyk(wan, cryst, nk, kpts, qpt, g_atm, out_eigens_k, out_eigens_kq)
3817 : :
3818 : : !Arguments ------------------------------------
3819 : : class(wan_t),intent(in) :: wan
3820 : : class(crystal_t),intent(in) :: cryst
3821 : : integer,intent(in) :: nk
3822 : : real(dp),intent(in) :: kpts(3,nk), qpt(3)
3823 : : complex(dp),intent(out) :: g_atm(wan%nwan, wan%nwan, wan%my_npert, nk)
3824 : : real(dp),optional,intent(out) :: out_eigens_k(wan%nwan,nk), out_eigens_kq(wan%nwan,nk)
3825 : :
3826 : : !Local variables-------------------------------
3827 : : integer :: ir, ik, ipc, nr_e, nr_p, nwan, my_npert, ncols_e, ncols_w
3828 : 0 : real(dp) :: kq(3), eigens_k(wan%nwan), eigens_kq(wan%nwan)
3829 : 0 : complex(dp),allocatable :: eikr(:), eiqr(:), u_k(:,:), u_kq(:,:), cbuf_e(:,:,:,:), cbuf_w(:,:,:), cmat_w(:,:)
3830 : : !************************************************************************
3831 : :
3832 : 0 : nr_p = wan%nr_p; nr_e = wan%nr_e; nwan = wan%nwan; my_npert = wan%my_npert
3833 : :
3834 [ # # # # : 0 : ABI_MALLOC(eikr, (nr_e))
# # # # #
# # # ]
3835 [ # # # # : 0 : ABI_MALLOC(eiqr, (nr_p))
# # # # #
# # # ]
3836 [ # # # # : 0 : ABI_MALLOC(u_k, (nwan, nwan))
# # # # #
# # # # #
# # ]
3837 [ # # # # : 0 : ABI_MALLOC(u_kq, (nwan, nwan))
# # # # #
# # # ]
3838 [ # # # # : 0 : ABI_MALLOC(cmat_w, (nwan, nwan))
# # # # #
# # # ]
3839 [ # # # # : 0 : ABI_MALLOC(cbuf_e, (nr_e, nwan, nwan, my_npert))
# # # # #
# # # # #
# # # # #
# # # #
# ]
3840 [ # # # # : 0 : ABI_MALLOC(cbuf_w, (nwan, nwan, my_npert))
# # # # #
# # # # #
# # # # #
# ]
3841 : :
3842 : : ! Prepare the q-dependent vertex once for the entire k batch:
3843 : : ! g(R_e,q) = sum_R_p exp(i q.R_p) g(R_e,R_p) / ndegen(R_p).
3844 [ # # ]: 0 : do ir=1,nr_p
3845 [ # # ]: 0 : eiqr(ir) = exp(+j_dpc * two_pi * dot_product(qpt, wan%r_p(:,ir))) / wan%ndegen_p(ir)
3846 : : end do
3847 : 0 : ncols_e = nr_e * nwan ** 2 * my_npert
3848 : 0 : call ZGEMV("T", nr_p, ncols_e, cone, wan%grpe_wwp, nr_p, eiqr, 1, czero, cbuf_e, 1)
3849 : :
3850 : 0 : ncols_w = nwan ** 2 * my_npert
3851 [ # # ]: 0 : do ik=1,nk
3852 [ # # ]: 0 : do ir=1,nr_e
3853 [ # # ]: 0 : eikr(ir) = exp(+j_dpc * two_pi * dot_product(kpts(:,ik), wan%r_e(:,ir))) / wan%ndegen_e(ir)
3854 : : end do
3855 : :
3856 : 0 : call wan%interp_ham(cryst, kpts(:,ik), u_k, eigens_k)
3857 [ # # ]: 0 : kq = kpts(:,ik) + qpt
3858 : 0 : call wan%interp_ham(cryst, kq, u_kq, eigens_kq)
3859 [ # # # # ]: 0 : if (present(out_eigens_k)) out_eigens_k(:,ik) = eigens_k
3860 [ # # # # ]: 0 : if (present(out_eigens_kq)) out_eigens_kq(:,ik) = eigens_kq
3861 : :
3862 : : ! g(k,q) in the Wannier gauge.
3863 : 0 : call ZGEMV("T", nr_e, ncols_w, cone, cbuf_e, nr_e, eikr, 1, czero, cbuf_w, 1)
3864 : :
3865 : : ! Rotate from the Wannier gauge to the interpolated electronic eigenstates.
3866 [ # # ]: 0 : do ipc=1,my_npert
3867 : 0 : call ZGEMM('N', 'N', nwan, nwan, nwan, cone, u_kq, nwan, cbuf_w(:,:,ipc), nwan, czero, cmat_w, nwan)
3868 : 0 : call ZGEMM('N', 'C', nwan, nwan, nwan, cone, cmat_w, nwan, u_k, nwan, czero, g_atm(:,:,ipc,ik), nwan)
3869 : : end do
3870 : : end do
3871 : :
3872 [ # # ]: 0 : ABI_FREE(eikr)
3873 [ # # ]: 0 : ABI_FREE(eiqr)
3874 [ # # ]: 0 : ABI_FREE(u_k)
3875 [ # # ]: 0 : ABI_FREE(u_kq)
3876 [ # # ]: 0 : ABI_FREE(cmat_w)
3877 [ # # ]: 0 : ABI_FREE(cbuf_e)
3878 [ # # ]: 0 : ABI_FREE(cbuf_w)
3879 : :
3880 [ # # # # ]: 0 : end subroutine wan_interp_eph_manyk
3881 : : !!***
3882 : :
3883 : : !!****f* m_mlwfovlp/wan_prepare_eph_q
3884 : : !! NAME
3885 : : !! wan_prepare_eph_q
3886 : : !!
3887 : : !! FUNCTION
3888 : : !! Fourier transform g(R_e,R_p) along R_p for one q-point. The result can be
3889 : : !! reused by multiple calls to wan_interp_eph_manyk_from_q with bounded k
3890 : : !! batches.
3891 : : !!
3892 : : !! SOURCE
3893 : :
3894 : 0 : subroutine wan_prepare_eph_q(wan, qpt, g_req)
3895 : :
3896 : : class(wan_t),intent(in) :: wan
3897 : : real(dp),intent(in) :: qpt(3)
3898 : : complex(dp),intent(out) :: g_req(wan%nr_e, wan%nwan, wan%nwan, wan%my_npert)
3899 : :
3900 : : integer :: ir, ncols_e
3901 : 0 : complex(dp) :: eiqr(wan%nr_p)
3902 : : !************************************************************************
3903 : :
3904 [ # # ]: 0 : do ir=1,wan%nr_p
3905 [ # # ]: 0 : eiqr(ir) = exp(+j_dpc * two_pi * dot_product(qpt, wan%r_p(:,ir))) / wan%ndegen_p(ir)
3906 : : end do
3907 : 0 : ncols_e = wan%nr_e * wan%nwan ** 2 * wan%my_npert
3908 : 0 : call ZGEMV("T", wan%nr_p, ncols_e, cone, wan%grpe_wwp, wan%nr_p, eiqr, 1, czero, g_req, 1)
3909 : :
3910 : 0 : end subroutine wan_prepare_eph_q
3911 : : !!***
3912 : :
3913 : : !!****f* m_mlwfovlp/wan_interp_eph_manyk_from_q
3914 : : !! NAME
3915 : : !! wan_interp_eph_manyk_from_q
3916 : : !!
3917 : : !! FUNCTION
3918 : : !! Interpolate the e-ph matrix elements for a k-point batch from a vertex
3919 : : !! previously transformed to q by wan_prepare_eph_q.
3920 : : !!
3921 : : !! SOURCE
3922 : :
3923 : 0 : subroutine wan_interp_eph_manyk_from_q(wan, cryst, nk, kpts, qpt, g_req, g_atm, out_eigens_k, out_eigens_kq)
3924 : :
3925 : : class(wan_t),intent(in) :: wan
3926 : : class(crystal_t),intent(in) :: cryst
3927 : : integer,intent(in) :: nk
3928 : : real(dp),intent(in) :: kpts(3,nk), qpt(3)
3929 : : complex(dp),intent(in) :: g_req(wan%nr_e, wan%nwan, wan%nwan, wan%my_npert)
3930 : : complex(dp),intent(out) :: g_atm(wan%nwan, wan%nwan, wan%my_npert, nk)
3931 : : real(dp),optional,intent(out) :: out_eigens_k(wan%nwan,nk), out_eigens_kq(wan%nwan,nk)
3932 : :
3933 : : integer :: ir, ik, ipc, ncols_w
3934 : 0 : real(dp) :: kq(3), eigens_k(wan%nwan), eigens_kq(wan%nwan)
3935 : 0 : complex(dp),allocatable :: eikr(:), u_k(:,:), u_kq(:,:), g_wan(:,:,:), cmat_w(:,:)
3936 : : !************************************************************************
3937 : :
3938 [ # # # # : 0 : ABI_MALLOC(eikr, (wan%nr_e))
# # # # #
# # # ]
3939 [ # # # # : 0 : ABI_MALLOC(u_k, (wan%nwan, wan%nwan))
# # # # #
# # # # #
# # ]
3940 [ # # # # : 0 : ABI_MALLOC(u_kq, (wan%nwan, wan%nwan))
# # # # #
# # # ]
3941 [ # # # # : 0 : ABI_MALLOC(g_wan, (wan%nwan, wan%nwan, wan%my_npert))
# # # # #
# # # # #
# # # # #
# ]
3942 [ # # # # : 0 : ABI_MALLOC(cmat_w, (wan%nwan, wan%nwan))
# # # # #
# # # ]
3943 : :
3944 : 0 : ncols_w = wan%nwan ** 2 * wan%my_npert
3945 [ # # ]: 0 : do ik=1,nk
3946 [ # # ]: 0 : do ir=1,wan%nr_e
3947 [ # # ]: 0 : eikr(ir) = exp(+j_dpc * two_pi * dot_product(kpts(:,ik), wan%r_e(:,ir))) / wan%ndegen_e(ir)
3948 : : end do
3949 : :
3950 : 0 : call wan%interp_ham(cryst, kpts(:,ik), u_k, eigens_k)
3951 [ # # ]: 0 : kq = kpts(:,ik) + qpt
3952 : 0 : call wan%interp_ham(cryst, kq, u_kq, eigens_kq)
3953 [ # # # # ]: 0 : if (present(out_eigens_k)) out_eigens_k(:,ik) = eigens_k
3954 [ # # # # ]: 0 : if (present(out_eigens_kq)) out_eigens_kq(:,ik) = eigens_kq
3955 : :
3956 : 0 : call ZGEMV("T", wan%nr_e, ncols_w, cone, g_req, wan%nr_e, eikr, 1, czero, g_wan, 1)
3957 [ # # ]: 0 : do ipc=1,wan%my_npert
3958 : : call ZGEMM('N', 'N', wan%nwan, wan%nwan, wan%nwan, cone, u_kq, wan%nwan, &
3959 : 0 : g_wan(:,:,ipc), wan%nwan, czero, cmat_w, wan%nwan)
3960 : : call ZGEMM('N', 'C', wan%nwan, wan%nwan, wan%nwan, cone, cmat_w, wan%nwan, &
3961 : 0 : u_k, wan%nwan, czero, g_atm(:,:,ipc,ik), wan%nwan)
3962 : : end do
3963 : : end do
3964 : :
3965 [ # # ]: 0 : ABI_FREE(eikr)
3966 [ # # ]: 0 : ABI_FREE(u_k)
3967 [ # # ]: 0 : ABI_FREE(u_kq)
3968 [ # # ]: 0 : ABI_FREE(g_wan)
3969 [ # # ]: 0 : ABI_FREE(cmat_w)
3970 : :
3971 [ # # # # ]: 0 : end subroutine wan_interp_eph_manyk_from_q
3972 : : !!***
3973 : :
3974 : : !!****f* m_mlwfovlp/wan_eph_kbatch_size
3975 : : !! NAME
3976 : : !! wan_eph_kbatch_size
3977 : : !!
3978 : : !! FUNCTION
3979 : : !! Return a k-batch size that bounds the combined complex local-perturbation
3980 : : !! and complete atomic-perturbation buffers. memory_mb defaults to 64 MiB.
3981 : : !!
3982 : : !! SOURCE
3983 : :
3984 : 0 : integer function wan_eph_kbatch_size(wan, nk, natom3, memory_mb) result(nk_batch)
3985 : :
3986 : : class(wan_t),intent(in) :: wan
3987 : : integer,intent(in) :: nk, natom3
3988 : : real(dp),optional,intent(in) :: memory_mb
3989 : :
3990 : : real(dp) :: limit_mb
3991 : : !************************************************************************
3992 : :
3993 : 0 : limit_mb = 64.0_dp
3994 [ # # ]: 0 : if (present(memory_mb)) limit_mb = memory_mb
3995 [ # # ]: 0 : ABI_CHECK(limit_mb > zero, "The Wannier e-ph k-batch memory limit must be positive")
3996 : : nk_batch = int(limit_mb * 1024.0_dp ** 2 / &
3997 : 0 : (16.0_dp * wan%nwan ** 2 * (wan%my_npert + natom3)))
3998 : 0 : nk_batch = max(1, min(nk, nk_batch))
3999 : :
4000 : 0 : end function wan_eph_kbatch_size
4001 : : !!***
4002 : :
4003 : : !!****f* m_mlwfovlp/wan_ncwrite_gwan
4004 : : !! NAME
4005 : : !! wan_ncwrite_gwan
4006 : : !!
4007 : : !! FUNCTION
4008 : : !! Write the e-ph matrix elements in the Wannier representation g(R_e,R_ph) to the GWAN.nc netcdf file.
4009 : : !!
4010 : : !! SOURCE
4011 : :
4012 : 0 : subroutine wan_ncwrite_gwan(wan, dtfil, cryst, ebands, pert_comm)
4013 : :
4014 : : !Arguments ------------------------------------
4015 : : class(wan_t),target,intent(in) :: wan
4016 : : type(datafiles_type),intent(in) :: dtfil
4017 : : type(crystal_t),intent(in) :: cryst
4018 : : type(ebands_t),intent(in) :: ebands
4019 : : type(xcomm_t),intent(in) :: pert_comm
4020 : :
4021 : : !Local variables-------------------------------
4022 : : !scalars
4023 : : integer :: spin, root_ncid, spin_ncid, ncerr, natom3, ount, ir, var_id, units(2), batch_size, idat, ndat
4024 : 0 : real(dp), contiguous, pointer :: rpt_d4(:,:,:,:), rpt_d6(:,:,:,:,:,:)
4025 : : character(len=fnlen) :: gwan_filepath, txt_path
4026 : 0 : complex(dp),target,allocatable :: cbuf5(:,:,:,:,:)
4027 : : character(len=500) :: msg
4028 : : !************************************************************************
4029 : :
4030 [ # # ]: 0 : units = [std_out, ab_out]
4031 : 0 : spin = wan%spin; natom3 = 3 * cryst%natom
4032 : :
4033 [ # # ]: 0 : gwan_filepath = strcat(dtfil%filnam_ds(4), "_GWAN.nc")
4034 : 0 : call wrtout(units, sjoin("- Writing e-ph matrix elements in the Wannier representation to file:", gwan_filepath))
4035 : :
4036 [ # # ]: 0 : if (spin == 1) then
4037 [ # # ]: 0 : NCF_CHECK(nctk_open_create(root_ncid, gwan_filepath, pert_comm%value))
4038 [ # # ]: 0 : NCF_CHECK(cryst%ncwrite(root_ncid))
4039 : : !NCF_CHECK(hdr%ncwrite(root_ncid))
4040 [ # # ]: 0 : NCF_CHECK(ebands%ncwrite(root_ncid))
4041 : : else
4042 [ # # ]: 0 : NCF_CHECK(nctk_open_modify(root_ncid, gwan_filepath, pert_comm%value))
4043 : : end if
4044 : :
4045 : : ! Create group for this spin and define dimensions.
4046 [ # # ]: 0 : NCF_CHECK(nf90_def_grp(root_ncid, strcat("gwan", "_spin", itoa(spin)), spin_ncid))
4047 : :
4048 : : ncerr = nctk_def_dims(spin_ncid, [ &
4049 : : nctkdim_t("nwan", wan%nwan), &
4050 : : nctkdim_t("natom3", natom3), &
4051 : : nctkdim_t("nr_h", wan%nr_h), &
4052 : : nctkdim_t("nr_e", wan%nr_e), &
4053 : : nctkdim_t("nr_p", wan%nr_p) &
4054 [ # # ]: 0 : ], defmode=.True.)
4055 [ # # ]: 0 : NCF_CHECK(ncerr)
4056 : :
4057 : : ncerr = nctk_def_arrays(spin_ncid, [ &
4058 : : nctkarr_t("r_h", "dp", "three, nr_h"), &
4059 : : nctkarr_t("r_e", "dp", "three, nr_e"), &
4060 : : nctkarr_t("r_p", "dp", "three, nr_p"), &
4061 : : nctkarr_t("ndegen_h", "int", "nr_h"), &
4062 : : nctkarr_t("ndegen_e", "int", "nr_e"), &
4063 : : nctkarr_t("ndegen_p", "int", "nr_p"), &
4064 : : nctkarr_t("hwan_r", "dp", "two, nr_h, nwan, nwan"), &
4065 : : nctkarr_t("grpe_wwp", "dp", "two, nr_p, nr_e, nwan, nwan, natom3") &
4066 [ # # ]: 0 : ])
4067 [ # # ]: 0 : NCF_CHECK(ncerr)
4068 : :
4069 : : ! Write data.
4070 [ # # ]: 0 : NCF_CHECK(nctk_set_datamode(spin_ncid))
4071 [ # # ]: 0 : NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("r_h"), wan%r_h))
4072 [ # # ]: 0 : NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("r_e"), wan%r_e))
4073 [ # # ]: 0 : NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("r_p"), wan%r_p))
4074 [ # # ]: 0 : NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("ndegen_h"), wan%ndegen_h))
4075 [ # # ]: 0 : NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("ndegen_e"), wan%ndegen_e))
4076 [ # # ]: 0 : NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("ndegen_p"), wan%ndegen_p))
4077 : :
4078 [ # # ]: 0 : call c_f_pointer(c_loc(wan%hwan_r), rpt_d4, [2, wan%nr_h, wan%nwan, wan%nwan])
4079 [ # # ]: 0 : NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("hwan_r"), rpt_d4))
4080 : :
4081 : : ! Take into account that the array might be distributed over perturbations.
4082 : : !NCF_CHECK(nctk_set_collective(spin_ncid, vid_spin("foo")))
4083 [ # # ]: 0 : call c_f_pointer(c_loc(wan%grpe_wwp), rpt_d6, [2, wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, wan%my_npert])
4084 : : ncerr = nf90_put_var(spin_ncid, vid_spin("grpe_wwp"), rpt_d6, &
4085 : : start=[1,1,1,1,1,wan%my_pert_start], &
4086 [ # # # # ]: 0 : count=[2, wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, wan%my_npert])
4087 [ # # ]: 0 : NCF_CHECK(ncerr)
4088 [ # # ]: 0 : NCF_CHECK(nf90_close(root_ncid))
4089 : :
4090 : 0 : call xmpi_barrier(pert_comm%value)
4091 : :
4092 : : ! Check spatial decay of the EP matrix elements in the wannier basis
4093 : : ! We plot: R_e, R_p, max_{m,n,nu} |g(m,n,nu;R_e,R_p)|
4094 [ # # ]: 0 : if (pert_comm%me == 0) then
4095 [ # # ]: 0 : NCF_CHECK(nctk_open_read(root_ncid, gwan_filepath, xmpi_comm_self))
4096 : : ! Get group for this spin.
4097 [ # # ]: 0 : NCF_CHECK(nf90_inq_ncid(root_ncid, strcat("gwan", "_spin", itoa(spin)), spin_ncid))
4098 : :
4099 [ # # ]: 0 : txt_path = strcat(dtfil%filnam_ds(4), "_spin", itoa(spin), "_GWAN.txt")
4100 [ # # ]: 0 : if (open_file(txt_path, msg, newunit=ount, form="formatted", action="write", status='unknown') /= 0) then
4101 : 0 : ABI_ERROR(msg)
4102 : : end if
4103 : 0 : write(ount, '(a)') '# R_e [Bohr] max_{m,n,nu} |g(m,n,nu R_e,:)| [Ha/Bohr] '
4104 : 0 : var_id = vid_spin("grpe_wwp")
4105 : : ! Perform IO in batches to keep memory at bay.
4106 : : ! FIXME
4107 : 0 : batch_size = 1
4108 [ # # # # : 0 : ABI_MALLOC(cbuf5, (wan%nr_p, batch_size, wan%nwan, wan%nwan, natom3))
# # # # #
# # # # #
# # # # #
# # # ]
4109 [ # # ]: 0 : call c_f_pointer(c_loc(cbuf5), rpt_d6, [2, wan%nr_p, batch_size, wan%nwan, wan%nwan, natom3])
4110 [ # # # # ]: 0 : do ir=1,wan%nr_e, batch_size
4111 : 0 : ndat = blocked_loop(ir, wan%nr_e, batch_size)
4112 : : !nctkarr_t("grpe_wwp", "dp", "two, nr_p, nr_e, nwan, nwan, natom3") &
4113 : : ncerr = nf90_get_var(spin_ncid, var_id, rpt_d6, &
4114 [ # # # # ]: 0 : start=[1,1,ir,1,1,1], count=[2, wan%nr_p, batch_size, wan%nwan, wan%nwan, natom3])
4115 [ # # ]: 0 : NCF_CHECK(ncerr)
4116 [ # # ]: 0 : do idat=1,ndat
4117 [ # # # # : 0 : write(ount, *) wan%rmod_e(ir+idat-1), maxval(abs(cbuf5(:,idat,:,:,:)))
# # # # #
# # # # #
# # ]
4118 : : end do
4119 : : end do
4120 [ # # ]: 0 : ABI_FREE(cbuf5)
4121 : :
4122 : 0 : close(ount)
4123 [ # # ]: 0 : NCF_CHECK(nf90_close(root_ncid))
4124 : : end if
4125 : :
4126 : : contains
4127 : 0 : integer function vid_spin(var_name)
4128 : : character(len=*),intent(in) :: var_name
4129 [ # # ]: 0 : vid_spin = nctk_idname(spin_ncid, var_name)
4130 : : end function vid_spin
4131 : :
4132 : : end subroutine wan_ncwrite_gwan
4133 : : !!***
4134 : :
4135 : : !!****f* m_mlwfovlp/wan_load_gwan
4136 : : !! NAME
4137 : : !! wan_load_gwan
4138 : : !!
4139 : : !! FUNCTION
4140 : : !! Read g(R_e, R_p) in the Wannier representation from an ABIWAN.nc file
4141 : : !!
4142 : : !! SOURCE
4143 : :
4144 : 0 : subroutine wan_load_gwan(wan, gwan_filepath, cryst, spin, nsppol, all_comm)
4145 : :
4146 : : !Arguments ------------------------------------
4147 : : class(wan_t),target,intent(inout) :: wan
4148 : : character(len=*),intent(in) :: gwan_filepath
4149 : : integer,intent(in) :: spin, nsppol
4150 : : type(crystal_t),intent(in) :: cryst
4151 : : type(xcomm_t),intent(in) :: all_comm ! , pert_comm
4152 : :
4153 : : !Local variables-------------------------------
4154 : : !scalars
4155 : : integer :: root_ncid, spin_ncid, ncerr, units(2)
4156 : : real(dp) :: cpu, wall, gflops
4157 : : logical,parameter :: keep_umats = .False.
4158 [ # # # # : 0 : type(crystal_t) :: gwan_cryst
# # # # #
# # # # #
# # # # #
# ]
4159 : 0 : real(dp), contiguous, pointer :: rpt_d6(:,:,:,:,:,:) !, rpt_d4(:,:,:,:)
4160 : : !************************************************************************
4161 : :
4162 [ # # ]: 0 : units = [std_out, ab_out]
4163 : 0 : call cwtime(cpu, wall, gflops, "start")
4164 [ # # ]: 0 : if (nsppol == 2) then
4165 : 0 : call wrtout(units, sjoin(" Reading g(R_e, R_p) for spin:", itoa(spin), " from GWAN file:", gwan_filepath))
4166 : : else
4167 : 0 : call wrtout(units, sjoin(" Reading g(R_e, R_p) from GWAN file:", gwan_filepath))
4168 : : end if
4169 : :
4170 [ # # ]: 0 : NCF_CHECK(nctk_open_read(root_ncid, gwan_filepath, all_comm%value))
4171 : :
4172 : 0 : call gwan_cryst%ncread(root_ncid)
4173 [ # # ]: 0 : if (cryst%compare(gwan_cryst, header=" Comparing input crystal with GWAN crystal.") /= 0) then
4174 : 0 : ABI_ERROR("Crystal structure from input and GWAN file do not agree! Check messages above!")
4175 : : end if
4176 : 0 : call gwan_cryst%free()
4177 : :
4178 : : ! Get netcdf group for this spin.
4179 [ # # ]: 0 : NCF_CHECK(nf90_inq_ncid(root_ncid, strcat("gwan", "_spin", itoa(spin)), spin_ncid))
4180 : :
4181 : : ! Read supercell lattice vectors.
4182 [ # # ]: 0 : NCF_CHECK(nctk_get_dim(spin_ncid, "nr_e", wan%nr_e))
4183 [ # # ]: 0 : NCF_CHECK(nctk_get_dim(spin_ncid, "nr_p", wan%nr_p))
4184 : :
4185 [ # # # # : 0 : ABI_MALLOC(wan%r_e, (3, wan%nr_e))
# # # # #
# # # #
# ]
4186 [ # # # # : 0 : ABI_MALLOC(wan%r_p, (3, wan%nr_p))
# # # # #
# # # #
# ]
4187 [ # # # # : 0 : ABI_MALLOC(wan%ndegen_e, (wan%nr_e))
# # # # #
# # # #
# ]
4188 [ # # # # : 0 : ABI_MALLOC(wan%ndegen_p, (wan%nr_p))
# # # # #
# # # #
# ]
4189 : :
4190 [ # # ]: 0 : NCF_CHECK(nf90_get_var(spin_ncid, vid_spin("r_e"), wan%r_e))
4191 [ # # ]: 0 : NCF_CHECK(nf90_get_var(spin_ncid, vid_spin("r_p"), wan%r_p))
4192 [ # # ]: 0 : NCF_CHECK(nf90_get_var(spin_ncid, vid_spin("ndegen_e"), wan%ndegen_e))
4193 [ # # ]: 0 : NCF_CHECK(nf90_get_var(spin_ncid, vid_spin("ndegen_p"), wan%ndegen_p))
4194 : :
4195 : : !call c_f_pointer(c_loc(wan%hwan_r), rpt_d4, [2, wan%nr_h, wan%nwan, wan%nwan])
4196 : : !NCF_CHECK(nf90_get_var(spin_ncid, vid_spin("hwan_r"), rpt_d4))
4197 : :
4198 : : ! TODO:
4199 : : ! Take into account that the array might be distributed over perturbations.
4200 : : !print *, "wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, wan%my_npert", wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, wan%my_npert
4201 [ # # # # : 0 : ABI_MALLOC(wan%grpe_wwp, (wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, wan%my_npert))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
4202 [ # # ]: 0 : call c_f_pointer(c_loc(wan%grpe_wwp), rpt_d6, [2, wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, wan%my_npert])
4203 : :
4204 : : ! nctkarr_t("grpe_wwp", "dp", "two, nr_p, nr_e, nwan, nwan, natom3") &
4205 [ # # ]: 0 : if (all_comm%nproc > 1) then
4206 [ # # ]: 0 : NCF_CHECK(nctk_set_collective(spin_ncid, vid_spin("grpe_wwp")))
4207 : : end if
4208 : : ncerr = nf90_get_var(spin_ncid, vid_spin("grpe_wwp"), rpt_d6, &
4209 : : start=[1, 1, 1, 1, 1, wan%my_pert_start], &
4210 [ # # # # ]: 0 : count=[2, wan%nr_p, wan%nr_e, wan%nwan, wan%nwan, wan%my_npert])
4211 [ # # ]: 0 : NCF_CHECK(ncerr)
4212 : :
4213 [ # # ]: 0 : NCF_CHECK(nf90_close(root_ncid))
4214 : 0 : call wrtout(units, " Reading of GWAN.nc file completed.")
4215 [ # # # # : 0 : call cwtime_report(" Reading Wannier e-ph matrix elements from GWAN.nc", cpu, wall, gflops)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
4216 : :
4217 : : contains
4218 : 0 : integer function vid_spin(var_name)
4219 : : character(len=*),intent(in) :: var_name
4220 : 0 : vid_spin = nctk_idname(spin_ncid, var_name)
4221 : : end function vid_spin
4222 : : end subroutine wan_load_gwan
4223 : : !!***
4224 : :
4225 : : !!****f* m_mlwfovlp/wan_interp_ebands
4226 : : !! NAME
4227 : : !! wan_interp_ebands
4228 : : !!
4229 : : !! FUNCTION
4230 : : !! Build new ebands_t object on a k-mesh via Wannier interpolation.
4231 : : !!
4232 : : !! INPUT
4233 : : !! cryst<crystal_t> = Crystalline structure.
4234 : : !! intp_kptrlatt(3,3) = New k-mesh
4235 : : !! intp_nshiftk= Number of shifts in new k-mesh.
4236 : : !! intp_shiftk(3,intp_nshiftk) = Shifts in new k-mesh.
4237 : : !! band_block(2)=Initial and final band index. If [0,0], all bands are used
4238 : : !!
4239 : : !! OUTPUT
4240 : : !! out_ebands: object with interpolated energies.
4241 : : !!
4242 : : !! NOTES
4243 : : !! Fermi level of the interpolated bands is not recomputed by this routine
4244 : : !! but copied from in_ebands.
4245 : : !!
4246 : : !! SOURCE
4247 : :
4248 [ # # # # : 0 : subroutine wan_interp_ebands(wan_spin, cryst, in_ebands, intp_kptrlatt, intp_nshiftk, intp_shiftk, out_ebands, comm)
# # # # #
# # # # #
# # # # #
# ]
4249 : :
4250 : : !Arguments ------------------------------------
4251 : : type(ebands_t),intent(in) :: in_ebands
4252 : : type(wan_t),intent(in) :: wan_spin(in_ebands%nsppol)
4253 : : type(crystal_t),intent(in) :: cryst
4254 : : integer,intent(in) :: intp_kptrlatt(3,3), intp_nshiftk, comm
4255 : : real(dp),intent(in) :: intp_shiftk(3,intp_nshiftk)
4256 : : type(ebands_t),intent(out) :: out_ebands
4257 : :
4258 : : !Local variables-------------------------------
4259 : : !scalars
4260 : : integer :: spin, ik, nwan, ierr, cnt, my_rank, nproc
4261 : : real(dp) :: cpu, wall, gflops
4262 : : !arrays
4263 : : integer :: band_block(2)
4264 : : real(dp) :: params(4)
4265 : 0 : real(dp),allocatable :: eigens_k(:)
4266 [ # # ]: 0 : complex(dp),allocatable :: u_k(:,:)
4267 : : !************************************************************************
4268 : :
4269 : 0 : my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
4270 : :
4271 : 0 : call cwtime(cpu, wall, gflops, "start")
4272 : :
4273 : : ! Build new ebands object with memory to be filled.
4274 [ # # ]: 0 : band_block(:) = [1, wan_spin(1)%max_nwan]
4275 : : out_ebands = in_ebands%interp_kmesh(cryst, params, intp_kptrlatt, intp_nshiftk, intp_shiftk, &
4276 [ # # # # : 0 : band_block, comm, malloc_only=.True.)
# # # # #
# # # # #
# # # # #
# # # ]
4277 [ # # # # : 0 : out_ebands%eig = zero
# # ]
4278 : :
4279 : : cnt = 0
4280 [ # # ]: 0 : do spin=1,in_ebands%nsppol
4281 : 0 : associate (wan => wan_spin(spin))
4282 : 0 : nwan = wan%nwan
4283 [ # # # # : 0 : ABI_MALLOC(u_k, (nwan, nwan))
# # # # #
# # # #
# ]
4284 [ # # # # : 0 : ABI_MALLOC(eigens_k, (nwan))
# # # # #
# # # ]
4285 [ # # ]: 0 : do ik=1,out_ebands%nkpt
4286 [ # # ]: 0 : cnt = cnt + 1; if (mod(cnt - 1, nproc) /= my_rank) cycle ! MPI parallelism inside comm.
4287 : 0 : call wan%interp_ham(cryst, out_ebands%kptns(:,ik), u_k, eigens_k)
4288 [ # # ]: 0 : out_ebands%eig(1:nwan, ik, spin) = eigens_k
4289 : : end do ! ik
4290 [ # # ]: 0 : ABI_FREE(u_k)
4291 [ # # # # ]: 0 : ABI_FREE(eigens_k)
4292 : : end associate
4293 : : end do ! spin
4294 : :
4295 : 0 : call xmpi_sum(out_ebands%eig, comm, ierr)
4296 : :
4297 : : ! Copy Fermi energies.
4298 : 0 : out_ebands%fermie = in_ebands%fermie
4299 : 0 : out_ebands%fermih = in_ebands%fermih
4300 : :
4301 : 0 : call cwtime_report(" Wannier interpolation of electronic bands", cpu, wall, gflops)
4302 : :
4303 : 0 : end subroutine wan_interp_ebands
4304 : : !!***
4305 : :
4306 [ + + + - : 9909192 : end module m_mlwfovlp
- - - - -
- # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
4307 : : !!***
|