Octopus
wannier90_interface.F90
Go to the documentation of this file.
1!! Copyright (C) 2017-2019 H. Huebener, N. Tancogne-Dejean
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use batch_oct_m
24 use comm_oct_m
26 use cube_oct_m
28 use debug_oct_m
30 use fft_oct_m
31 use global_oct_m
32 use grid_oct_m
33 use io_oct_m
36 use ions_oct_m
37 use, intrinsic :: iso_fortran_env
42 use loct_oct_m
44 use mesh_oct_m
47 use mpi_oct_m
51 use parser_oct_m
56 use space_oct_m
57 use string_oct_m
62 use types_oct_m
63 use unit_oct_m
65 use utils_oct_m
68
69 implicit none
70
71 integer :: w90_what, w90_mode
72 integer(int64) :: w90_what_default
73
74 integer :: ierr
75 integer :: dim, idim
76 integer :: ii, nik, iter, nst
77
78 type(restart_t) :: restart
79 type(electrons_t), pointer :: sys
80 logical :: w90_spinors, scdm_proj, w90_scdm
81 integer :: w90_nntot, w90_num_bands, w90_num_kpts ! w90 input parameters
82 integer, allocatable :: w90_nnk_list(:,:) !
83 character(len=80) :: w90_prefix ! w90 input file prefix
84 integer :: w90_num_wann ! input paramter
85 real(real64), allocatable :: w90_proj_centers(:,:) ! projections centers
86 integer, allocatable :: w90_proj_lmr(:,:) ! definitions for real valued Y_lm*R_r
87 integer :: w90_nproj ! number of such projections
88 integer, allocatable :: w90_spin_proj_component(:) ! up/down flag
89 real(real64), allocatable :: w90_spin_proj_axis(:,:) ! spin axis (not implemented)
90 integer :: w90_num_exclude
91 logical, allocatable :: exclude_list(:) ! list of excluded bands
92 integer, allocatable :: band_index(:) ! band index after exclusion
93 logical :: read_td_states
94 integer :: w90_spin_channel
95
96 ! scdm variables
97 integer, allocatable :: jpvt(:)
98 complex(real64), allocatable :: uk(:,:,:) ! SCDM-Wannier gauge matrices U(k)
99 complex(real64), allocatable :: psi(:,:)
100 complex(real64), allocatable :: chi(:,:), chi_diag(:,:),chi2(:,:)
101 real(real64), allocatable :: chi_eigenval(:), occ_temp(:)
102 real(real64) :: scdm_mu, scdm_sigma, smear, kvec(3), factor(3)
103 integer :: ist, jst, ik, idir
104
105 integer(int64) :: how
106
107 call global_init()
108 call parser_init()
109
110 call messages_init()
111 call io_init()
112
114
117
118 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
119 sys => electrons_t(global_namespace, int(option__calculationmode__dummy, int32))
120 call sys%init_parallelization(mpi_world)
121
122 !%Variable Wannier90Prefix
123 !%Type string
124 !%Default w90
125 !%Section Utilities::oct-wannier90
126 !%Description
127 !% Prefix for wannier90 files
128 !%End
129 call parse_variable(global_namespace, 'Wannier90Prefix', 'w90', w90_prefix)
130 if (w90_prefix == 'w90') then
131 message(1) = "oct-wannier90: the prefix is set by default to w90"
132 call messages_info(1)
133 end if
134
135 !%Variable Wannier90Mode
136 !%Type integer
137 !%Default 0
138 !%Section Utilities::oct-wannier90
139 !%Description
140 !% Specifies which stage of the Wannier90 interface to use
141 !%Option none 0
142 !% Nothing is done.
143 !%Option w90_setup 1
144 !% Writes parts of the wannier90 input file <tt>w90_prefix.win</tt> corresponding to
145 !% the octopus inp file. Importantly it generates the correct form of Monkhorst-Pack mesh
146 !% written to the file w90_kpoints that has to be used in a gs calculation of Octopus by
147 !% as <tt> include w90_kpoints </tt> instead of the <tt>%KpointsGrid</tt> block.
148 !%Option w90_output 2
149 !% Generates the relevant files for a wannier90 run, specified by the variable <tt>W90_interface_files</tt>.
150 !% This needs files previously generated
151 !% by <tt>wannier90.x -pp w90 </tt>
152 !%Option w90_wannier 3
153 !% Parse the output of wannier90 to generate the Wannier states on the real-space grid.
154 !% The states will be written in the folder wannier. By default, the states are written as
155 !% binary files, similar to the Kohn-Sham states.
156 !%
157 !% Not implemented for spinor states.
158 !%End
159 call parse_variable(global_namespace, 'Wannier90Mode', 0, w90_mode)
160
161 if (w90_mode == 0) then
162 message(1) = "Wannier90Mode must be set to a value different from 0."
163 call messages_fatal(1)
164 end if
165
166 !%Variable Wannier90Files
167 !%Type flag
168 !%Default w90_mmn + w90_amn + w90_eig
169 !%Section Utilities::oct-wannier90
170 !%Description
171 !% Specifies which files to generate.
172 !% Example: <tt>w90_mmn + w90_unk</tt>
173 !%Option w90_mmn bit(1)
174 !% (see Wannier90 documentation)
175 !%Option w90_unk bit(2)
176 !% (see Wannier90 documentation)
177 !%Option w90_amn bit(3)
178 !% (see Wannier90 documentation)
179 !%Option w90_eig bit(4)
180 !% Eigenvalues. See Wannier90 documentation for more details.
181 !%Option w90_spn bit(5)
182 !% Spin. See Wannier90 documentation for more details.
183 !%End
184 w90_what_default = option__wannier90files__w90_mmn + option__wannier90files__w90_amn + option__wannier90files__w90_eig
185 if (sys%st%d%ispin == spinors) w90_what_default = w90_what_default + option__wannier90files__w90_spn
186 call parse_variable(global_namespace, 'Wannier90Files', w90_what_default, w90_what)
187
188 !%Variable Wannier90UseTD
189 !%Type logical
190 !%Default no
191 !%Section Utilities::oct-wannier90
192 !%Description
193 !% By default oct-wannier90 uses the ground-state states to compute the necessary information.
194 !% By setting this variable to yes, oct-wannier90 will use the TD states instead.
195 !%End
196 call parse_variable(global_namespace, 'Wannier90UseTD', .false., read_td_states)
197
198 !%Variable Wannier90UseSCDM
199 !%Type logical
200 !%Default no
201 !%Section Utilities::oct-wannier90
202 !%Description
203 !% By default oct-wannier90 uses the projection method to generate the .amn file.
204 !% By setting this variable to yes, oct-wannier90 will use SCDM method instead.
205 !%End
206 call parse_variable(global_namespace, 'Wannier90UseSCDM', .false., w90_scdm)
207 if (w90_scdm) then
208 !%Variable SCDMsigma
209 !%Type float
210 !%Default 0.2
211 !%Section Utilities::oct-wannier90
212 !%Description
213 !% Broadening of SCDM smearing function.
214 !%End
215 call parse_variable(global_namespace, 'SCDMsigma', 0.2_real64, scdm_sigma)
216
217 !%Variable SCDMmu
218 !%Type float
219 !%Section Utilities::oct-wannier90
220 !%Description
221 !% Energy range up to which states are considered for SCDM.
222 !%End
223 call parse_variable(global_namespace, 'SCDMmu', m_huge, scdm_mu)
224 end if
225
226 if (sys%kpoints%use_symmetries) then
227 message(1) = 'oct-wannier90: k-points symmetries are not allowed'
228 call messages_fatal(1)
229 end if
230 if (sys%kpoints%use_time_reversal) then
231 message(1) = 'oct-wannier90: time-reversal symmetry is not allowed'
232 call messages_fatal(1)
233 end if
234 if (sys%kpoints%reduced%nshifts > 1) then
235 message(1) = 'oct-wannier90: Wannier90 does not allow for multiple shifts of the k-point grid'
236 call messages_fatal(1)
237 end if
238
239
240 if (sys%st%d%ispin /= unpolarized) then
241 call messages_experimental("oct-wannier90 with SpinComponnents /= unpolarized")
242 end if
243
244 w90_spinors = .false.
245 w90_spin_channel = 1
246
247 ! "Correct" rlattice/klattice for Wannier90 (3D periodicity assumed here).
248 factor = m_one
249 do idir = sys%space%periodic_dim+1, sys%space%dim
250 factor(idir) = m_two * sys%gr%box%bounding_box_l(idir)
251 end do
252 call sys%ions%latt%scale(factor)
253
254 ! create setup files
255 select case (w90_mode)
256 case (option__wannier90mode__w90_setup)
257 call wannier90_setup(sys%ions, sys%kpoints, sys%space)
258
259 ! load states and calculate interface files
260 case (option__wannier90mode__w90_output)
261 call wannier90_output()
262
263 case (option__wannier90mode__w90_wannier)
265
266 ! normal interface run
267 call states_elec_allocate_wfns(sys%st, sys%gr, wfs_type = type_cmplx, skip=exclude_list)
268 if (read_td_states) then
269 call restart%init(global_namespace, restart_td, restart_type_load, &
270 sys%mc, ierr, sys%gr)
271 else
272 call restart%init(global_namespace, restart_gs, restart_type_load, &
273 sys%mc, ierr, sys%gr)
274 end if
275
276 if (ierr == 0) then
277 call states_elec_look(restart, nik, dim, nst, ierr)
278 if (dim == sys%st%d%dim .and. nik == sys%kpoints%reduced%npoints .and. nst >= sys%st%nst) then
279 call states_elec_load(restart, global_namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
280 ierr, iter, label = ": wannier90", skip=exclude_list)
281 else
282 write(message(1),'(a)') 'Restart structure not commensurate.'
283 call messages_fatal(1)
284 end if
285 end if
286 call restart%end()
287
288 call generate_wannier_states(sys%space, sys%gr, sys%ions, sys%st, sys%kpoints)
289 case default
290 message(1) = "Wannier90Mode is set to an unsupported value."
291 call messages_fatal(1)
292 end select
293
294 safe_deallocate_a(exclude_list)
295 safe_deallocate_a(band_index)
296 safe_deallocate_a(w90_nnk_list)
297 safe_deallocate_a(w90_proj_centers)
298 safe_deallocate_a(w90_proj_lmr)
299
300 safe_deallocate_p(sys)
301 call fft_all_end()
302 call io_end()
304 call messages_end()
305 call parser_end()
306 call global_end()
307
308contains
309
310 ! --------------------------------------------------------------------------
311 subroutine wannier90_setup(ions, kpoints, space)
312 type(ions_t), intent(in) :: ions
313 type(kpoints_t), intent(in) :: kpoints
314 class(space_t), intent(in) :: space
315
316 character(len=80) :: filename
317 integer :: w90_win, ia, axis(3), npath
318
319 push_sub(wannier90_setup)
320
321 assert(space%dim == 3)
322
323 ! open win file
324 filename = trim(adjustl(w90_prefix)) //'.win'
325 w90_win = io_open(trim(filename), global_namespace, action='write')
326
327 write(w90_win,'(a)') '# this file has been created by the Octopus wannier90 utility'
328 write(w90_win,'(a)') ' '
329
330 ! write direct lattice vectors (in angstrom)
331 write(w90_win,'(a)') 'begin unit_cell_cart'
332 write(w90_win,'(a)') 'Ang'
333 do idim = 1,3
334 write(w90_win,'(f13.8,f13.8,f13.8)') units_from_atomic(unit_angstrom, ions%latt%rlattice(1:3,idim))
335 end do
336 write(w90_win,'(a)') 'end unit_cell_cart'
337 write(w90_win,'(a)') ' '
338
339 write(w90_win,'(a)') 'begin atoms_frac'
340 do ia = 1, ions%natoms
341 write(w90_win,'(a,2x,f13.8,f13.8,f13.8)') trim(ions%atom(ia)%label), ions%latt%cart_to_red(ions%pos(:, ia))
342 end do
343 write(w90_win,'(a)') 'end atoms_frac'
344 write(w90_win,'(a)') ' '
345
346 ! This is a default value. In practice, one should use projections
347 write(w90_win,'(a)') 'use_bloch_phases = .true.'
348 write(w90_win,'(a)') ' '
349
350 write(w90_win,'(a10,i4)') 'num_bands ', sys%st%nst
351 write(w90_win,'(a9,i4)') 'num_wann ', sys%st%nst
352 write(w90_win,'(a)') ' '
353
354 if (sys%st%d%ispin == spinors) then
355 write(w90_win,'(a)') 'spinors = .true.'
356 end if
357 if (sys%st%d%ispin == spin_polarized) then
358 write(w90_win, '(a)') 'spin = up'
359 end if
360
361 ! This is for convenience. This is needed for plotting the Wannier states, if requested.
362 write(w90_win,'(a)') 'write_u_matrices = .true.'
363 write(w90_win,'(a)') 'write_xyz = .true.'
364 write(w90_win,'(a)') ' '
365
366 if (kpoints%reduced%npoints == 1) then
367 write(w90_win,'(a)') 'gamma_only = .true.'
368 write(w90_win,'(a)') ' '
369 else
370 if (.not. parse_is_defined(global_namespace, 'KPointsGrid')) then
371 message(1) = 'oct-wannier90: need Monkhorst-Pack grid. Please specify %KPointsGrid'
372 call messages_fatal(1)
373 end if
374
375 ! In case the user used also a k-point path, we ignore it
376 npath = kpoints%nkpt_in_path()
377
378 axis(1:3) = kpoints%nik_axis(1:3)
379 assert(product(kpoints%nik_axis(1:3)) == kpoints%reduced%npoints - npath)
380
381 write(w90_win,'(a8,i4,i4,i4)') 'mp_grid =', axis(1:3)
382 write(w90_win,'(a)') ' '
383 write(w90_win,'(a)') 'begin kpoints '
384 ! Put a minus sign here for the wrong convention in Octopus
385
386 do ii = 1, kpoints%reduced%npoints-npath
387 write(w90_win,'(f13.8,f13.8,f13.8)') - kpoints%reduced%red_point(1:3,ii)
388 end do
389 write(w90_win,'(a)') 'end kpoints '
390 end if
391
392 call io_close(w90_win)
393
394 pop_sub(wannier90_setup)
395
396 end subroutine wannier90_setup
397
398 ! --------------------------------------------------------------------------
399 subroutine wannier90_output()
400 integer :: ik_real
401
402 push_sub(wannier90_output)
403
405
406 ! normal interface run
407 call states_elec_allocate_wfns(sys%st, sys%gr, wfs_type = type_cmplx, skip=exclude_list)
408 if (read_td_states) then
409 call restart%init(global_namespace, restart_td, restart_type_load, &
410 sys%mc, ierr, sys%gr)
411 else
412 call restart%init(global_namespace, restart_gs, restart_type_load, &
413 sys%mc, ierr, sys%gr)
414 end if
415
416 if (ierr == 0) then
417 call states_elec_look(restart, nik, dim, nst, ierr)
418 if (sys%st%d%ispin == spin_polarized) then
419 nik = nik / 2
420 end if
421 if (dim == sys%st%d%dim .and. nik == sys%kpoints%reduced%npoints .and. nst >= sys%st%nst) then
422 call states_elec_load(restart, global_namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
423 ierr, iter, label = ": wannier90", skip=exclude_list)
424 else
425 write(message(1),'(a)') 'Restart structure not commensurate.'
426 call messages_fatal(1)
427 end if
428 end if
429 call restart%end()
430
431 if (w90_scdm) then
432 nik = w90_num_kpts
433 safe_allocate(jpvt(1:sys%gr%np_global*sys%st%d%dim))
434 safe_allocate(psi(1:sys%gr%np, 1:sys%st%d%dim))
435 safe_allocate(occ_temp(1:w90_num_bands))
436
437 ! smear the states at gamma
438 do ist = 1, w90_num_bands
439 occ_temp(ist)= sys%st%occ(ist, 1)
440 sys%st%occ(ist, 1)=m_half*loct_erfc((sys%st%eigenval(ist, 1)-scdm_mu) / scdm_sigma)
441 end do
442
443 call zstates_elec_rrqr_decomposition(sys%st, sys%namespace, sys%gr, w90_num_bands, .true., 1, jpvt)
444
445 ! reset occupations at gamma
446 do ist = 1, w90_num_bands
447 sys%st%occ(ist, 1) = occ_temp(ist)
448 end do
449
450 safe_allocate(uk(1:w90_num_bands, 1:w90_num_bands, 1:nik))
451
452 ! auxiliary arrays for scdm procedure
453 safe_allocate(chi(1:w90_num_bands, 1:w90_num_bands))
454 safe_allocate(chi_diag(1:w90_num_bands, 1:w90_num_bands))
455 safe_allocate(chi2(1:w90_num_bands, 1:w90_num_bands))
456 safe_allocate(chi_eigenval(1:w90_num_bands))
457
458 chi(1:w90_num_bands, 1:w90_num_bands) = m_zero
459
460 do ik = 1, nik
461 kvec(:) = sys%kpoints%reduced%point(:, ik)
462
463 if (sys%st%d%ispin == spin_polarized) then
464 ik_real = (ik-1)*2 + w90_spin_channel
465 else
466 ik_real = ik
467 end if
468
469 do ist = 1, w90_num_bands
470 call states_elec_get_state(sys%st, sys%gr, ist, ik_real, psi)
471 smear=m_half * loct_erfc((sys%st%eigenval(ist, ik_real) - scdm_mu) / scdm_sigma)
472 ! NOTE: here check for domain parallelization
473 do jst = 1, w90_num_bands
474 chi(ist, jst) = smear * conjg(psi(jpvt(jst), 1)) &
475 * exp(m_zi * dot_product(sys%gr%x(jpvt(jst), 1:3), kvec(1:3)))
476 end do
477 end do
478
479 ! loewdin orhtogonalization of chi.chi
480 ! this can also be done with SVD, which might be more stable!?
481 chi_diag = matmul(conjg(transpose(chi)), chi)
482 call lalg_eigensolve(w90_num_bands, chi_diag, chi_eigenval)
483 chi2 = conjg(transpose(chi_diag))
484
485 !we need the eigenvalues to be >0
486 if (any(chi_eigenval(:) .lt. m_zero)) then
487 message(1) = 'SCDM Wannierization failed because chi matrix is'
488 message(2) = 'ill conditioned. Try increasingin scdm_sigma and/or'
489 message(3) = 'change scdm_mu.'
490 call messages_fatal(3)
491 end if
492
493 do ist = 1, w90_num_bands
494 chi_eigenval(ist) = m_one / sqrt(chi_eigenval(ist))
495 chi2(ist, 1:w90_num_bands) = chi_eigenval(ist) * chi2(ist, 1:w90_num_bands)
496 end do
497 ! the loewdin result would be: matmul(chi_diag,chi2)
498 ! to get the wannier gauge U(k) we multiply this with the original chi
499 uk(:,:,ik) = matmul(chi, matmul(chi_diag,chi2))
500
501 end do
502
503 safe_deallocate_a(chi)
504 safe_deallocate_a(psi)
505 safe_deallocate_a(chi_diag)
506 safe_deallocate_a(chi2)
507 safe_deallocate_a(chi_eigenval)
508 safe_deallocate_a(jpvt)
509 safe_deallocate_a(psi)
510 safe_deallocate_a(occ_temp)
511 end if
512
513 ! ---- actual interface work ----------
514 if (bitand(w90_what, option__wannier90files__w90_mmn) /= 0) then
515 call create_wannier90_mmn(sys%gr, sys%st)
516 end if
517
518 if (bitand(w90_what, option__wannier90files__w90_unk) /= 0) then
519 call write_unk(sys%space, sys%gr, sys%st)
520 end if
521
522 if (bitand(w90_what, option__wannier90files__w90_amn) /= 0) then
523 call create_wannier90_amn(sys%space, sys%gr, sys%ions%latt, sys%st, sys%kpoints)
524 end if
525
526 if (bitand(w90_what, option__wannier90files__w90_eig) /= 0) then
528 end if
529
530 if (bitand(w90_what, option__wannier90files__w90_spn) /= 0) then
531 call create_wannier90_spn(sys%gr, sys%st)
532 end if
533
534 safe_deallocate_a(uk)
535 safe_deallocate_a(w90_spin_proj_component)
536 safe_deallocate_a(w90_spin_proj_axis)
537
538 pop_sub(wannier90_output)
539 end subroutine wannier90_output
540
541 ! --------------------------------------------------------------------------
542 subroutine read_wannier90_files()
543 integer :: w90_nnkp, itemp, dummyint, io
544 character(len=80) :: filename, dummy, dummy1, dummy2, line
545 logical :: exist, parse_is_ok
546 real(real64) :: dummyr(7)
547
548 push_sub(read_wannier90_files)
549
550 w90_num_kpts = product(sys%kpoints%nik_axis(1:3))
551 assert(w90_num_kpts == sys%st%nik)
552
553
554 w90_num_exclude = 0
555
556 ! open nnkp file
557 filename = trim(adjustl(w90_prefix)) //'.nnkp'
558
559 message(1) = "oct-wannier90: Parsing "//filename
560 call messages_info(1)
561
562 inquire(file=filename,exist=exist)
563 if (.not. exist) then
564 message(1) = 'oct-wannier90: Cannot find specified Wannier90 nnkp file.'
565 write(message(2),'(a)') 'Please run wannier90.x -pp '// trim(adjustl(w90_prefix)) // ' first.'
566 call messages_fatal(2)
567 end if
568
569 parse_is_ok = .false.
570
571 ! check number of k-points
572 w90_nnkp = io_open(trim(filename), global_namespace, action='read')
573 do
574 read(w90_nnkp, *, iostat=io) dummy, dummy1
575 if (io == iostat_end) exit
576
577 if (dummy == 'begin' .and. dummy1 == 'kpoints') then
578 read(w90_nnkp,*) itemp
579 if (itemp /= w90_num_kpts) then
580 message(1) = 'oct-wannier90: wannier90 setup seems to have been done with a different number of k-points.'
581 call messages_fatal(1)
582 else
583 parse_is_ok = .true.
584 exit
585 end if
586 end if
587 end do
588 call io_close(w90_nnkp)
589
590 if (.not. parse_is_ok) then
591 message(1) = 'oct-wannier90: Did not find the kpoints block in nnkp file'
592 call messages_fatal(1)
593 end if
594 parse_is_ok = .false.
595
596 ! read from nnkp file
597 ! find the nnkpts block
598 w90_nnkp = io_open(trim(filename), global_namespace, action='read', position='rewind')
599 do
600 read(w90_nnkp, *, iostat=io) dummy, dummy1
601 if (io == iostat_end) exit !End of file
602
603 if (dummy == 'begin' .and. dummy1 == 'nnkpts') then
604 read(w90_nnkp,*) w90_nntot
605 safe_allocate(w90_nnk_list(1:5, 1:w90_num_kpts * w90_nntot))
606 do ii = 1, w90_num_kpts * w90_nntot
607 read(w90_nnkp,*) w90_nnk_list(1:5, ii)
608 end do
609 !make sure we are at the end of the block
610 read(w90_nnkp,*) dummy
611 if (dummy /= 'end') then
612 message(1) = 'oct-wannier90: There dont seem to be enough k-points in nnkpts file to.'
613 call messages_fatal(1)
614 end if
615 parse_is_ok = .true.
616 exit
617 end if
618 end do
619
620 if (.not. parse_is_ok) then
621 message(1) = 'oct-wannier90: Did not find nnkpts block in nnkp file'
622 call messages_fatal(1)
623 end if
624
625 ! read from nnkp file
626 ! find the exclude block
627 safe_allocate(exclude_list(1:sys%st%nst))
628 !By default we use all the bands
629 exclude_list(1:sys%st%nst) = .false.
630 rewind(w90_nnkp)
631 do
632 read(w90_nnkp, *, iostat=io) dummy, dummy1
633 if (io == iostat_end) exit !End of file
634 if (dummy == 'begin' .and. dummy1 == 'exclude_bands') then
635 read(w90_nnkp, *) w90_num_exclude
636 do ii = 1, w90_num_exclude
637 read(w90_nnkp, *) itemp
638 if(itemp > sys%st%nst) then
639 message(1) = 'oct-wannier90: The exclude_bands list contains a state index higher than the number of states.'
640 call messages_fatal(1)
641 end if
642 exclude_list(itemp) = .true.
643 end do
644 !make sure we are at the end of the block
645 read(w90_nnkp, *) dummy
646 if (dummy /= 'end') then
647 message(1) = 'oct-wannier90: There dont seem to be enough bands in exclude_bands list.'
648 call messages_fatal(1)
649 end if
650 exit
651 end if
652 end do
653 call io_close(w90_nnkp)
654
655 !We get the number of bands
656 w90_num_bands = sys%st%nst - w90_num_exclude
657
658 safe_allocate(band_index(1:sys%st%nst))
659 itemp = 0
660 do ii = 1, sys%st%nst
661 if (exclude_list(ii)) cycle
662 itemp = itemp + 1
663 band_index(ii) = itemp
664 end do
665
666 if (bitand(w90_what, option__wannier90files__w90_amn) /= 0 &
667 .or. w90_mode == option__wannier90mode__w90_wannier ) then
668 ! parse file again for definitions of projections
669 w90_nnkp = io_open(trim(filename), global_namespace, action='read', position='rewind')
670
671 do
672 read(w90_nnkp, *, iostat=io) dummy, dummy1
673 if (io == iostat_end) then !End of file
674 message(1) = 'oct-wannier90: Did not find projections block in w90.nnkp file'
675 call messages_fatal(1)
676 end if
677
678 if (dummy == 'begin' .and. (dummy1 == 'projections' .or. dummy1 == 'spinor_projections')) then
679
680 if (dummy1 == 'spinor_projections') then
681 w90_spinors = .true.
682 if (sys%st%d%ispin /= spinors) then
683 message(1) = 'oct-wannier90: Spinor = .true. is only valid with spinors wavefunctions.'
684 call messages_fatal(1)
685 end if
686
687 message(1) = 'oct-wannier90: Spinor interface incomplete. Note there is no quantization axis implemented'
688 call messages_warning(1)
689 else
690 if (sys%st%d%ispin == spinors) then
691 message(1) = 'oct-wannier90: Octopus has spinors wavefunctions but spinor_projections is not defined.'
692 message(2) = 'oct-wannier90: Please check the input file for wannier 90.'
693 call messages_fatal(2)
694 end if
695 end if
696
697 read(w90_nnkp, *) w90_nproj
698 ! num_wann is given in w90.win, not double checked here
699 ! I assume that the wannier90.x -pp run has checked this
700 w90_num_wann = w90_nproj
701 ! In case of no projections, we use the number of bands
702 if(w90_nproj == 0) w90_num_wann = w90_num_bands
703
704 safe_allocate(w90_proj_centers(1:3, 1:w90_nproj))
705 safe_allocate(w90_proj_lmr(1:w90_nproj, 1:3))
706 if (w90_spinors) then
707 safe_allocate(w90_spin_proj_component(1:w90_nproj))
708 end if
709 if (w90_spinors) then
710 safe_allocate(w90_spin_proj_axis(1:w90_nproj, 1:3))
711 end if
712
713 do ii = 1, w90_nproj
714 read(w90_nnkp, *) w90_proj_centers(1:3, ii), w90_proj_lmr(ii, 1:3)
715 ! skip a line for now
716 read(w90_nnkp, *) dummyr(1:7)
717 if (w90_spinors) then
718 read(w90_nnkp, *) w90_spin_proj_component(ii), w90_spin_proj_axis(ii, 1:3)
719 ! use octopus spindim conventions
720 if (w90_spin_proj_component(ii) == -1) w90_spin_proj_component(ii) = 2
721 end if
722 end do
723 !make sure we are at the end of the block
724 read(w90_nnkp, *) dummy
725 if (dummy /= 'end') then
726 message(1) = 'oct-wannier90: There dont seem to be enough projections in nnkpts file to.'
727 call messages_fatal(1)
728 end if
729 exit
730 end if
731 end do
732
733 ! look for auto_projection block
734 scdm_proj = .false.
735 do
736 read(w90_nnkp, *, iostat=io) dummy, dummy1
737 if (io == iostat_end) exit !End of file
738
739 if (dummy == 'begin' .and. dummy1 == 'auto_projections') then
740 scdm_proj = .true.
741 read(w90_nnkp, *) w90_nproj
742 w90_num_wann = w90_nproj
743
744 if (.not. w90_scdm) then
745 message(1) = 'oct-wannier90: Found auto_projections block. Currently the only implemented automatic way'
746 message(2) = 'oct-wannier90: to compute projections is the SCDM method.'
747 message(3) = 'oct-wannier90: Please set Wannier90UseSCDM = yes in the inp file.'
748 call messages_fatal(3)
749 end if
750
751 if (w90_nproj /= w90_num_bands) then
752 message(1) = 'oct-wannier90: In auto_projections block first row needs to be equal to num_bands.'
753 call messages_fatal(1)
754 end if
755 read(w90_nnkp, *) dummyint
756 if (dummyint /= 0) then
757 message(1) = 'oct-wannier90: The second row in auto_projections has to be 0, per Wannier90 documentation.'
758 call messages_fatal(1)
759 end if
760 end if
761 end do
762 call io_close(w90_nnkp)
763
764 end if
765
766 message(1) = "oct-wannier90: Finished parsing "//filename
767 call messages_info(1)
768
769 ! Look extra variables variable
770 ! open win file
771 filename = trim(adjustl(w90_prefix)) //'.win'
772 message(1) = "oct-wannier90: Parsing "//filename
773 call messages_info(1)
774 w90_nnkp = io_open(trim(filename), global_namespace, action='read', position='rewind')
775 do
776 read(w90_nnkp, fmt='(a)', iostat=io) line
777 if (io == iostat_end) exit !End of file
778 if (index(line, '=') > 0) then
779 read(line, *, iostat=io) dummy, dummy2, dummy1
780 else
781 read(line, *, iostat=io) dummy, dummy1
782 end if
783
784 !Spin
785 if (dummy == 'spin') then
786 if (sys%st%d%ispin /= spin_polarized) then
787 message(1) = 'oct-wannier90: The variable spin is set for a non spin-polarized calculation.'
788 call messages_fatal(1)
789 end if
790
791 if (dummy1 == 'up') then
792 w90_spin_channel = 1
793 else if (dummy1 == 'down') then
794 w90_spin_channel = 2
795 else
796 message(1) = 'oct-wannier90: Error parsing the variable spin.'
797 call messages_fatal(1)
798 end if
799 end if
800 end do
801 call io_close(w90_nnkp)
802
803 if (sys%st%d%ispin == spin_polarized) then
804 write(message(1), '(a,i1)') 'oct-wannier90: Using spin channel ', w90_spin_channel
805 call messages_info(1)
806 end if
807
808 message(1) = "oct-wannier90: Finished parsing "//filename
809 call messages_info(1)
810
811 pop_sub(read_wannier90_files)
812
813 end subroutine read_wannier90_files
814
815 ! --------------------------------------------------------------------------
816 subroutine create_wannier90_mmn(mesh, st)
817 class(mesh_t), intent(in) :: mesh
818 type(states_elec_t), target, intent(in) :: st
819
820 integer :: ist, jst, ik, ip, w90_mmn, iknn, idim, ibind
821 real(real64) :: Gcart(3)
822 integer :: G(3)
823 character(len=80) :: filename
824 complex(real64), allocatable :: overlap(:)
825 complex(real64), allocatable :: psim(:,:), psin(:,:), phase(:)
826 type(wfs_elec_t), pointer :: batch
827 integer :: inode, node_fr, node_to
828 type(mpi_request) :: send_req
829
830 push_sub(create_wannier90_mmn)
831
832 call profiling_in("W90_MMN")
833
834 if (st%parallel_in_states) then
835 call messages_not_implemented("w90_mmn output with states parallelization")
836 end if
837
838 message(1) = "Info: Computing the overlap matrix"
839 call messages_info(1)
840
841
842 filename = './'// trim(adjustl(w90_prefix))//'.mmn'
843 w90_mmn = io_open(trim(filename), global_namespace, action='write')
844
845 ! write header
846 if (mpi_world%is_root()) then
847 write(w90_mmn,*) 'Created by oct-wannier90'
848 write(w90_mmn,*) w90_num_bands, w90_num_kpts, w90_nntot
849 end if
850
851 safe_allocate(psim(1:mesh%np, 1:st%d%dim))
852 safe_allocate(psin(1:mesh%np, 1:st%d%dim))
853 safe_allocate(phase(1:mesh%np))
854 safe_allocate(overlap(1:w90_num_bands))
855
856
857 ! loop over the pairs specified in the nnkp file (read before in init)
858 do ii = 1, w90_num_kpts * w90_nntot
859 ik = w90_nnk_list(1, ii)
860 iknn = w90_nnk_list(2, ii)
861 g(1:3) = w90_nnk_list(3:5, ii)
862 if (mpi_world%is_root()) write(w90_mmn, '(I10,2x,I10,2x,I3,2x,I3,2x,I3)') ik, iknn, g
863
864 ! For spin-polarized calculations, we select the right k-point
865 if (sys%st%d%ispin == spin_polarized) then
866 ik = (ik-1)*2 + w90_spin_channel
867 iknn = (iknn-1)*2 + w90_spin_channel
868 end if
869
870
871 ! Only treat local k-points
872 if(ik >= st%d%kpt%start .and. ik <= st%d%kpt%end) then
873
874 ! Wannier90 treats everything fully periodic
875 ! Conversion is done with the 3D "correct" klattice
876 call kpoints_to_absolute(sys%ions%latt, real(g, real64) , gcart)
877
878 ! Phase that gives u_{n,k+G}(r) from u_{nk}(r)
879 ! Here the minus sign of Octopus cancels with minus sign of the input G
880 ! (ik and iknn correspond in the list to minus the k-points in Octopus)
881 if (any(g /= 0)) then
882 do ip = 1, mesh%np
883 phase(ip) = exp(-m_zi*dot_product(mesh%x(ip,1:3), gcart(1:3)))
884 end do
885 end if
886
887 end if
888
889 ! Loop over distributed bands
890 do jst = 1, st%nst
891 if (exclude_list(jst)) cycle
892
893 ! Communication for the local states
894 if ( .not. st%d%kpt%parallel .and. .not. st%parallel_in_states) then
895 call states_elec_get_state(st, mesh, jst, iknn, psin)
896 else
897 node_fr = -1
898 node_to = -1
899 do inode = 0, st%d%kpt%mpi_grp%size-1
900 if(iknn >= st%st_kpt_task(inode,3) .and. iknn <= st%st_kpt_task(inode,4)) then
901 node_fr = inode
902 end if
903 if(ik >= st%st_kpt_task(inode,3) .and. ik <= st%st_kpt_task(inode,4)) then
904 node_to = inode
905 end if
906 end do
907 assert(node_fr > -1)
908 assert(node_to > -1)
909
910 send_req = mpi_request_null
911 ! We have locally the k-point
912 if (state_kpt_is_local(st, jst, iknn)) then
913 call states_elec_get_state(st, mesh, jst, iknn, psin)
914 ! We send it only if we don`t want to use it locally
915 if(node_to /= st%d%kpt%mpi_grp%rank) then
916 call st%d%kpt%mpi_grp%isend(psin, mesh%np*st%d%dim, mpi_double_complex, node_to, send_req)
917 end if
918 end if
919 ! We receive the desired state, only if it is not a local one
920 if(node_to == st%d%kpt%mpi_grp%rank .and. node_to /= node_fr) then
921 call st%d%kpt%mpi_grp%recv(psin, mesh%np*st%d%dim, mpi_double_complex, node_fr)
922 end if
923 if (send_req /= mpi_request_null) then
924 call st%d%kpt%mpi_grp%wait(send_req)
925 end if
926 end if
927
928 overlap = m_zero
929
930 if(ik >= st%d%kpt%start .and. ik <= st%d%kpt%end) then
931
932 ! Do not apply the phase if the phase factor is null
933 if (any(g /= 0)) then
934 ! add phase
935 do idim = 1, st%d%dim
936 do ip = 1, mesh%np
937 psin(ip, idim) = psin(ip, idim) * phase(ip)
938 end do
939 end do
940 end if
941
942
943 ! See Eq. (25) in PRB 56, 12847 (1997)
944 ! Loop over local k-points
945 do ist = 1, st%nst
946 if (exclude_list(ist)) cycle
947
948 batch => st%group%psib(st%group%iblock(ist), ik)
949
950 select case (batch%status())
951 case (batch_not_packed)
952 overlap(band_index(ist)) = m_z0
953 do idim = 1, st%d%dim
954 ibind = batch%inv_index((/ist, idim/))
955 overlap(band_index(ist)) = overlap(band_index(ist)) + &
956 zmf_dotp(mesh, batch%zff_linear(:, ibind), psin(:,idim), reduce = .false.)
957 end do
958 !Not properly done at the moment
960 call states_elec_get_state(st, mesh, ist, ik, psim)
961 overlap(band_index(ist)) = zmf_dotp(mesh, st%d%dim, psim, psin, reduce = .false.)
962 end select
963 end do !ist
964 end if
965
966 call profiling_in("W90_MMN_REDUCE")
967 call mesh%allreduce(overlap)
968 call profiling_out("W90_MMN_REDUCE")
969
970 if(st%d%kpt%parallel) then
971 call comm_allreduce(st%d%kpt%mpi_grp, overlap)
972 end if
973
974 ! write to W90 file
975 if (mpi_world%is_root()) then
976 do ist = 1, st%nst
977 if (exclude_list(ist)) cycle
978 write(w90_mmn,'(e18.10,2x,e18.10)') overlap(band_index(ist))
979 end do
980 end if
981
982 end do !jst
983 end do
984
985 call io_close(w90_mmn)
986
987 safe_deallocate_a(psim)
988 safe_deallocate_a(psin)
989 safe_deallocate_a(phase)
990 safe_deallocate_a(overlap)
991
992 call profiling_out("W90_MMN")
993
994 pop_sub(create_wannier90_mmn)
995
996 end subroutine create_wannier90_mmn
997
998 ! --------------------------------------------------------------------------
999 subroutine create_wannier90_eig()
1000 integer :: ist, ik, w90_eig
1001 character(len=80) :: filename
1002
1003 push_sub(create_wannier90_eig)
1004
1005 if (sys%st%parallel_in_states) then
1006 call messages_not_implemented("w90_eig output with states parallelization")
1007 end if
1008
1009 if (mpi_world%is_root()) then
1010 filename = './'//trim(adjustl(w90_prefix))//'.eig'
1011 w90_eig = io_open(trim(filename), global_namespace, action='write')
1012 do ik = 1, w90_num_kpts
1013 do ist = 1, sys%st%nst
1014 if (exclude_list(ist)) cycle
1015 if (sys%st%d%ispin /= spin_polarized) then
1016 write(w90_eig,'(I5,2x,I8,2x,e18.10)') band_index(ist), ik, &
1017 units_from_atomic(unit_ev, sys%st%eigenval(ist, ik))
1018 else
1019 write(w90_eig,'(I5,2x,I8,2x,e18.10)') band_index(ist), ik, &
1020 units_from_atomic(unit_ev, sys%st%eigenval(ist, (ik-1)*2+w90_spin_channel))
1021 end if
1022 end do
1023 end do
1024
1025 call io_close(w90_eig)
1026 end if
1027
1028 pop_sub(create_wannier90_eig)
1029 end subroutine create_wannier90_eig
1030
1031 ! --------------------------------------------------------------------------
1032 subroutine write_unk(space, mesh, st)
1033 class(space_t), intent(in) :: space
1034 class(mesh_t), intent(in) :: mesh
1035 type(states_elec_t), intent(in) :: st
1036
1037 integer :: ist, ik, unk_file, ispin
1038 integer :: ix, iy, iz
1039 character(len=80) :: filename
1040 complex(real64), allocatable :: psi(:)
1041 type(cube_t) :: cube
1042 type(cube_function_t) :: cf
1043
1044 push_sub(write_unk)
1045
1046 if (st%d%kpt%parallel) then
1047 call messages_not_implemented("w90_unk output with k-point parallelization")
1048 end if
1049
1050 if (sys%gr%parallel_in_domains) then
1051 call messages_not_implemented("w90_unk output with domain parallelization")
1052 end if
1053
1054 if (st%parallel_in_states) then
1055 call messages_not_implemented("w90_unk output with states parallelization")
1056 end if
1057
1058 call messages_experimental("Wannier90Files = w90_unk")
1059
1060
1061 safe_allocate(psi(1:mesh%np))
1062
1063 call cube_init(cube, mesh%idx%ll, global_namespace, space, mesh%spacing, &
1064 mesh%coord_system, need_partition=.not.mesh%parallel_in_domains)
1065 call cube_init_cube_map(cube, mesh)
1066
1067 call zcube_function_alloc_rs(cube, cf)
1068
1069 do ik = 1, w90_num_kpts
1070 do ispin = 1, st%d%dim
1071 if (mpi_world%is_root()) then
1072 write(filename, '(a,i5.5,a1,i1)') './UNK', ik,'.', ispin
1073 unk_file = io_open(trim(filename), global_namespace, action='write', form='unformatted')
1074 ! write header
1075 write(unk_file) mesh%idx%ll(1:mesh%idx%dim), ik, w90_num_bands
1076 end if
1077
1078 ! states
1079 do ist = 1, st%nst
1080 if (exclude_list(ist)) cycle
1081
1082 if (sys%st%d%ispin /= spin_polarized) then
1083 call states_elec_get_state(st, mesh, ispin, ist, ik, psi)
1084 else
1085 call states_elec_get_state(st, mesh, ispin, ist, (ik-1)*2+w90_spin_channel, psi)
1086 end if
1087
1088 ! put the density in the cube
1089 ! Note: At the moment this does not work for domain parallelization
1090 if (cube%parallel_in_domains) then
1091 assert(.not. cube%parallel_in_domains)
1092 else
1093 call zmesh_to_cube(mesh, psi, cube, cf)
1094 end if
1095
1096 if (mpi_world%is_root()) then
1097 write(unk_file) (((cf%zrs(ix,iy,iz), ix=1,cube%rs_n_global(1)), iy=1,cube%rs_n_global(2)), iz=1,cube%rs_n_global(3))
1098 end if
1099 end do
1100 if (mpi_world%is_root()) call io_close(unk_file)
1101 end do
1102 end do
1103
1104 call dcube_function_free_rs(cube, cf)
1105 call cube_end(cube)
1106
1107 safe_deallocate_a(psi)
1108
1109 pop_sub(write_unk)
1110
1111 end subroutine write_unk
1112
1113 ! --------------------------------------------------------------------------
1114 subroutine create_wannier90_amn(space, mesh, latt, st, kpoints)
1115 class(space_t), intent(in) :: space
1116 class(mesh_t), intent(in) :: mesh
1117 type(lattice_vectors_t), intent(in) :: latt
1118 type(states_elec_t), intent(in) :: st
1119 type(kpoints_t), intent(in) :: kpoints
1120
1121 integer :: ist, ik, w90_amn, idim, iw, ip, ik_real
1122 real(real64) :: center(3), kpoint(3), threshold
1123 character(len=80) :: filename
1124 complex(real64), allocatable :: psi(:,:), phase(:), projection(:)
1125 real(real64), allocatable :: ylm(:)
1126 type(orbitalset_t), allocatable :: orbitals(:)
1128 push_sub(create_wannier90_amn)
1129 call profiling_in("W90_AMN")
1130
1131 if (st%parallel_in_states) then
1132 call messages_not_implemented("w90_amn output with states parallelization")
1133 end if
1134
1135 filename = './'// trim(adjustl(w90_prefix))//'.amn'
1136 w90_amn = io_open(trim(filename), global_namespace, action='write')
1137
1138 ! write header
1139 if (mpi_world%is_root()) then
1140 write(w90_amn,*) 'Created by oct-wannier90'
1141 write(w90_amn,*) w90_num_bands, w90_num_kpts, w90_num_wann
1142 end if
1143
1144 if (scdm_proj) then
1145
1146 message(1) = "Info: Writing projections obtained from SCDM."
1147 call messages_info(1)
1148
1149 if (st%d%kpt%parallel) then
1150 call messages_not_implemented("w90_amn output with k-point parallelization")
1151 end if
1152
1153
1154 do ik = 1, w90_num_kpts
1155 do ist = 1, st%nst
1156 if (exclude_list(ist)) cycle
1157 if (mpi_world%is_root()) then
1158 do iw = 1, w90_nproj
1159 write (w90_amn,'(I5,2x,I5,2x,I5,2x,e18.10,2x,e18.10)') band_index(ist), iw, ik, uk(band_index(ist),iw,ik)
1160 end do
1161 end if
1162 end do !ist
1163 end do! ik
1164
1165 else
1166
1167 message(1) = "Info: Computing the projection matrix"
1168 call messages_info(1)
1169
1170 !We use the variable AOThreshold to deterine the threshold on the radii of the atomic orbitals
1171 call parse_variable(global_namespace, 'AOThreshold', 0.001_real64, threshold)
1172
1173 safe_allocate(orbitals(1:w90_nproj))
1174 ! precompute orbitals
1175 do iw=1, w90_nproj
1176 call orbitalset_init(orbitals(iw))
1177
1178 orbitals(iw)%norbs = 1
1179 orbitals(iw)%ndim = 1
1180 orbitals(iw)%radius = -log(threshold)
1181 orbitals(iw)%use_submesh = .false.
1182
1183 ! cartesian coordinate of orbital center
1184 center(1:3) = latt%red_to_cart(w90_proj_centers(1:3, iw))
1185 call submesh_init(orbitals(iw)%sphere, space, mesh, latt, center, orbitals(iw)%radius)
1186
1187 ! get dorb as submesh points
1188 safe_allocate(ylm(1:orbitals(iw)%sphere%np))
1189 ! (this is a routine from pwscf)
1190 call ylm_wannier(ylm, w90_proj_lmr(iw,1), w90_proj_lmr(iw,2), &
1191 orbitals(iw)%sphere%r, orbitals(iw)%sphere%rel_x, orbitals(iw)%sphere%np)
1192
1193 ! apply radial function
1194 if (w90_proj_lmr(iw,3) == 1) then
1195 do ip = 1,orbitals(iw)%sphere%np
1196 ylm(ip) = ylm(ip)*m_two*exp(-orbitals(iw)%sphere%r(ip))
1197 end do
1198 else
1199 call messages_not_implemented("oct-wannier90: r/=1 for the radial part")
1200 end if
1201
1202 safe_allocate(orbitals(iw)%zorb(1:orbitals(iw)%sphere%np, 1, 1))
1203 orbitals(iw)%zorb(1:orbitals(iw)%sphere%np, 1, 1) = ylm(1:orbitals(iw)%sphere%np)
1204 safe_deallocate_a(ylm)
1205
1206 safe_allocate(orbitals(iw)%phase(1:orbitals(iw)%sphere%np, st%d%kpt%start:st%d%kpt%end))
1207 orbitals(iw)%phase(:,:) = m_z0
1208 safe_allocate(orbitals(iw)%eorb_mesh(1:mesh%np, 1, 1, st%d%kpt%start:st%d%kpt%end))
1209 orbitals(iw)%eorb_mesh(:,:,:,:) = m_z0
1210
1211 call orbitalset_update_phase(orbitals(iw), space%dim, st%d%kpt, kpoints, st%d%ispin == spin_polarized, &
1212 kpt_max = w90_num_kpts)
1213
1214 end do
1215
1216 safe_allocate(psi(1:mesh%np, 1:st%d%dim))
1217 safe_allocate(phase(1:mesh%np))
1218 safe_allocate(projection(1:w90_nproj))
1219
1220 do ik = 1, w90_num_kpts
1221 kpoint(1:space%dim) = kpoints%get_point(ik)
1222 do ip = 1, mesh%np
1223 phase(ip) = exp(-m_zi* sum(mesh%x(ip, 1:space%dim) * kpoint(1:space%dim)))
1224 end do
1225
1226 !For spin-polarized calculations, we select the right k-point
1227 if (st%d%ispin == spin_polarized) then
1228 ik_real = (ik-1)*2 + w90_spin_channel
1229 else
1230 ik_real = ik
1231 end if
1232
1233
1234 do ist = 1, st%nst
1235 if (exclude_list(ist)) cycle
1236
1237 projection = m_zero
1238
1239 if(ik_real >= st%d%kpt%start .and. ik_real <= st%d%kpt%end) then
1240 call states_elec_get_state(st, mesh, ist, ik_real, psi)
1241
1242 do idim = 1, st%d%dim
1243 !The minus sign is here is for the wrong convention of Octopus
1244 do ip = 1, mesh%np
1245 psi(ip, idim) = psi(ip, idim)*phase(ip)
1246 end do
1247 end do
1248
1249 do iw = 1, w90_nproj
1250 idim = 1
1251 if (w90_spinors) idim = w90_spin_proj_component(iw)
1252
1253 !At the moment the orbitals do not depend on idim
1254 !The idim index for eorb_mesh would be for a spin-resolved orbital like j=1/2
1255 projection(iw) = zmf_dotp(mesh, psi(1:mesh%np,idim), &
1256 orbitals(iw)%eorb_mesh(1:mesh%np,1,1,ik_real), reduce = .false.)
1257 end do
1258
1259 call profiling_in("W90_AMN_REDUCE")
1260 call mesh%allreduce(projection)
1261 call profiling_out("W90_AMN_REDUCE")
1262 end if
1263
1264 if(st%d%kpt%parallel) then
1265 call comm_allreduce(st%d%kpt%mpi_grp, projection)
1266 end if
1267
1268 if (mpi_world%is_root()) then
1269 do iw = 1, w90_nproj
1270 write (w90_amn,'(I5,2x,I5,2x,I5,2x,e18.10,2x,e18.10)') band_index(ist), iw, ik, projection(iw)
1271 end do
1272 end if
1273 end do !ist
1274 end do !ik
1275
1276 safe_deallocate_a(psi)
1277 safe_deallocate_a(phase)
1278 safe_deallocate_a(projection)
1279
1280 do iw = 1, w90_nproj
1281 call orbitalset_end(orbitals(iw))
1282 end do
1283 safe_deallocate_a(orbitals)
1284 end if
1285
1286 call io_close(w90_amn)
1287
1288 call profiling_out("W90_AMN")
1289
1290 pop_sub(create_wannier90_amn)
1291
1292 end subroutine create_wannier90_amn
1293
1294 ! --------------------------------------------------------------------------
1298 subroutine create_wannier90_spn(mesh, st)
1299 class(mesh_t), intent(in) :: mesh
1300 type(states_elec_t), target, intent(in) :: st
1301
1302 integer :: ist, jst, ik, w90_spn, counter
1303 character(len=80) :: filename
1304 complex(real64), allocatable :: spin(:,:,:)
1305 complex(real64), allocatable :: psim(:,:), psin(:,:)
1306 complex(real64) :: dot_upup, dot_updown, dot_downup, dot_downdown
1307
1308 push_sub(create_wannier90_spn)
1309 call profiling_in("W90_SPN")
1310
1311 assert(st%d%ispin == spinors)
1312
1313 if (st%parallel_in_states) then
1314 call messages_not_implemented("w90_spn output with states parallelization")
1315 end if
1316
1317 message(1) = "Info: Computing the spin file"
1318 call messages_info(1)
1319
1320 filename = './'// trim(adjustl(w90_prefix))//'.spn'
1321 w90_spn = io_open(trim(filename), global_namespace, action='write')
1322
1323 ! write header
1324 if (mpi_world%is_root()) then
1325 write(w90_spn,*) 'Created by oct-wannier90'
1326 write(w90_spn,*) w90_num_bands, w90_num_kpts
1327 end if
1328
1329 safe_allocate(psim(1:mesh%np, 1:st%d%dim))
1330 safe_allocate(psin(1:mesh%np, 1:st%d%dim))
1331 safe_allocate(spin(1:3, 1:(w90_num_bands*(w90_num_bands+1))/2, 1:w90_num_kpts))
1332 spin = m_zero
1333
1334 ! loop over the pairs specified in the nnkp file (read before in init)
1335 do ik = st%d%kpt%start, st%d%kpt%end
1336 counter = 0
1337 do jst = 1, st%nst
1338 if (exclude_list(jst)) cycle
1339
1340 call states_elec_get_state(st, mesh, jst, ik, psim)
1341 do ist = 1, jst
1342 if (exclude_list(ist)) cycle
1343
1344 counter = counter + 1
1345
1346 call states_elec_get_state(st, mesh, ist, ik, psin)
1347
1348 dot_upup = zmf_dotp(mesh, psin(:, 1), psim(:, 1), reduce = .false.)
1349 dot_downdown = zmf_dotp(mesh, psin(:, 2), psim(:, 2), reduce = .false.)
1350 dot_updown = zmf_dotp(mesh, psin(:, 1), psim(:, 2), reduce = .false.)
1351 dot_downup = zmf_dotp(mesh, psin(:, 2), psim(:, 1), reduce = .false.)
1352
1353 spin(1, counter, ik) = dot_updown + dot_downup
1354 spin(2, counter, ik) = -m_zi * dot_updown + m_zi * dot_downup
1355 spin(3, counter, ik) = dot_upup - dot_downdown
1356 end do !ist
1357 end do
1358 end do
1359
1360 call profiling_in("W90_SPN_REDUCE")
1361 call mesh%allreduce(spin)
1362
1363 if(st%d%kpt%parallel) then
1364 call comm_allreduce(st%d%kpt%mpi_grp, spin)
1365 end if
1366 call profiling_out("W90_SPN_REDUCE")
1367
1368 ! write to W90 file
1369 if (mpi_world%is_root()) then
1370 do ik = 1, w90_num_kpts
1371 counter = 0
1372 do jst = 1, st%nst
1373 if (exclude_list(jst)) cycle
1374
1375 do ist = 1, jst
1376 if (exclude_list(ist)) cycle
1377
1378 counter = counter + 1
1379 write(w90_spn, '(e18.10,2x,e18.10)') spin(1, counter, ik)
1380 write(w90_spn, '(e18.10,2x,e18.10)') spin(2, counter, ik)
1381 write(w90_spn, '(e18.10,2x,e18.10)') spin(3, counter, ik)
1382 end do
1383 end do
1384 end do !ik
1385 end if
1386
1387 call io_close(w90_spn)
1388
1389 safe_deallocate_a(psim)
1390 safe_deallocate_a(psin)
1391 safe_deallocate_a(spin)
1392
1393 call profiling_out("W90_SPN")
1394
1395 pop_sub(create_wannier90_spn)
1396 end subroutine create_wannier90_spn
1397
1398
1399 ! --------------------------------------------------------------------------
1400 subroutine generate_wannier_states(space, mesh, ions, st, kpoints)
1401 class(space_t), intent(in) :: space
1402 class(mesh_t), intent(in) :: mesh
1403 type(ions_t), intent(in) :: ions
1404 type(states_elec_t), intent(in) :: st
1405 type(kpoints_t), intent(in) :: kpoints
1406
1407 integer :: w90_u_mat, w90_xyz, nwann, nik
1408 integer :: ik, iw, iw2, ip, ipmax, rankmax, idmmax
1409 real(real64), allocatable :: centers(:,:)
1410 complex(real64), allocatable :: Umnk(:,:,:)
1411 complex(real64), allocatable :: zwn(:,:), psi(:,:), phase(:)
1412 character(len=MAX_PATH_LEN) :: fname
1413 real(real64) :: kpoint(3), wmod, wmodmax, xx(space%dim)
1414 character(len=2) :: dum
1415 logical :: exist
1416 type(unit_t) :: fn_unit
1417 complex(real64) :: scal
1418
1419 push_sub(generate_wannier_states)
1420
1421 message(1) = "oct-wannier90: Constructing the Wannier states from the U matrix."
1422 call messages_info(1)
1423
1424 inquire(file=trim(trim(adjustl(w90_prefix))//'_centres.xyz'),exist=exist)
1425 if (.not. exist) then
1426 message(1) = 'oct-wannier90: Cannot find the Wannier90 file seedname_centres.xyz.'
1427 write(message(2),'(a)') 'Please run wannier90.x with "write_xyz=.true." in '// trim(adjustl(w90_prefix)) // '.'
1428 call messages_fatal(2)
1429 end if
1430
1431 w90_xyz = io_open(trim(trim(adjustl(w90_prefix))//'_centres.xyz'), global_namespace, action='read')
1432
1433 safe_allocate(centers(1:3, 1:w90_num_wann))
1434 !Skip two lines
1435 read(w90_xyz, *)
1436 read(w90_xyz, *)
1437 do iw = 1, w90_num_wann
1438 read(w90_xyz, *) dum, centers(1:3, iw)
1439 ! Wannier90 outputs the coordinates in angstrom
1440 centers(1:3, iw) = units_to_atomic(unit_angstrom, centers(1:3, iw))
1441 end do
1442 call io_close(w90_xyz)
1443
1444
1445 inquire(file=trim(trim(adjustl(w90_prefix))//'_u_dis.mat'),exist=exist)
1446 if (exist) then
1447 message(1) = 'oct-wannier90: Calculation of Wannier states with disentanglement is not yet supported.'
1448 call messages_fatal(1)
1449 end if
1450
1451 inquire(file=trim(trim(adjustl(w90_prefix))//'_u.mat'),exist=exist)
1452 if (.not. exist) then
1453 message(1) = 'oct-wannier90: Cannot find the Wannier90 seedname_u.mat file.'
1454 write(message(2),'(a)') 'Please run wannier90.x with "write_u_matrices=.true." in '// trim(adjustl(w90_prefix)) // '.'
1455 call messages_fatal(2)
1456 end if
1457 w90_u_mat = io_open(trim(trim(adjustl(w90_prefix))//'_u.mat'), global_namespace, action='read')
1458
1459
1460 !Skip one line
1461 read(w90_u_mat, *)
1462 !Read num_kpts, num_wann, num_wann for consistency check
1463 read(w90_u_mat, *) nik, nwann, nwann
1464 if (nik /= w90_num_kpts .or. nwann /= w90_num_wann) then
1465 print *, w90_num_wann, w90_num_kpts, nik, nwann
1466 message(1) = "The file contains U matrices is inconsistent with the .win file."
1467 call messages_fatal(1)
1468 end if
1469
1470 safe_allocate(umnk(1:w90_num_wann, 1:w90_num_wann, 1:w90_num_kpts))
1471
1472 do ik = 1, w90_num_kpts
1473 !Skip one line
1474 read(w90_u_mat, *)
1475 !Skip one line (k-point coordinate)
1476 read(w90_u_mat, *)
1477 read(w90_u_mat, '(f15.10,sp,f15.10)') ((umnk(iw, iw2, ik), iw=1, w90_num_wann), iw2=1, w90_num_wann)
1478 end do
1479
1480 call io_close(w90_u_mat)
1481
1482 !We read the output format for the Wannier states
1483 call parse_variable(global_namespace, 'OutputFormat', 0, how)
1484 if (how == 0) then
1485 message(1) = "OutputFormat must be specified for outputing Wannier functions."
1486 call messages_fatal(1)
1487 end if
1488
1489 call io_mkdir('wannier', global_namespace)
1490
1491 !Computing the Wannier states in the primitive cell, from the U matrices
1492 safe_allocate(zwn(1:mesh%np, 1:st%d%dim))
1493 safe_allocate(psi(1:mesh%np, 1:st%d%dim))
1494 safe_allocate(phase(1:mesh%np))
1496 do iw = 1, w90_num_wann
1497
1498 zwn(:, :) = m_z0
1499
1500 do ik = 1, w90_num_kpts
1501
1502 if (.not. (ik >= st%d%kpt%start .and. ik <= st%d%kpt%end)) cycle
1503
1504 kpoint(1:space%dim) = kpoints%get_point(ik, absolute_coordinates=.true.)
1505
1506 ! We compute the Wannier orbital on a grid centered around the Wannier function
1507 ! The minus sign is here is for the wrong convention of Octopus
1508 do ip = 1, mesh%np
1509 xx = mesh%x(ip, 1:space%dim)-centers(1:space%dim, iw)
1510 xx = ions%latt%fold_into_cell(xx)
1511 phase(ip) = exp(-m_zi* sum( xx * kpoint(1:space%dim)))
1512 end do
1513
1514 do iw2 = 1, st%nst
1515 if (exclude_list(iw2)) cycle
1516
1517 if (st%d%ispin /= spin_polarized) then
1518 call states_elec_get_state(st, mesh, iw2, ik, psi)
1519 else
1520 call states_elec_get_state(st, mesh, iw2, (ik-1)*2+w90_spin_channel, psi)
1521 end if
1522
1523 do idim = 1, st%d%dim
1524 do ip = 1, mesh%np
1525 zwn(ip, idim) = zwn(ip, idim) + umnk(band_index(iw2), iw, ik) * psi(ip, idim) * phase(ip)
1526 end do
1527 end do
1528 end do!iw2
1529 end do!ik
1530
1531 if(st%d%kpt%parallel) then
1532 call comm_allreduce(st%d%kpt%mpi_grp, zwn)
1533 end if
1534
1535 ! Following what Wannier90 is doing, we fix the global phase by setting the max to be real
1536 ! We also normalize to the number of k-point at this step
1537 if (sys%st%d%ispin /= spinors) then
1538 ipmax = 0
1539 idmmax= 0
1540 wmodmax = m_zero
1541 do idim = 1, st%d%dim
1542 do ip = 1, mesh%np
1543 wmod = real(zwn(ip, idim)*conjg(zwn(ip, idim)), real64)
1544 if (wmod > wmodmax) then
1545 ipmax = ip
1546 wmodmax = wmod
1547 idmmax = idim
1548 end if
1549 end do
1550 end do
1551 scal = sqrt(wmodmax)/zwn(ipmax, idmmax)/w90_num_kpts
1552 call mesh_minmaxloc(mesh, wmodmax, rankmax, mpi_maxloc)
1553 call mesh%mpi_grp%bcast(scal, 1, mpi_double_complex, rankmax)
1554 call lalg_scal(mesh%np, st%d%dim, scal, zwn)
1555 end if
1556
1557 ! Output the Wannier states
1558 fn_unit = sqrt(units_out%length**(-space%dim))
1559 do idim = 1, st%d%dim
1560 if (st%d%ispin == spinors) then
1561 write(fname, '(a,i3.3,a4,i1)') 'wannier-', iw, '-isp', idim
1562 else
1563 write(fname, '(a,i3.3,a4,i1)') 'wannier-', iw
1564 end if
1565 call zio_function_output(how, "wannier", trim(fname), global_namespace, space, mesh, &
1566 zwn(:, idim), fn_unit, ierr, pos=ions%pos, atoms=ions%atom, grp = st%dom_st_kpt_mpi_grp)
1567 end do
1568
1569 ! Checking the ratio imag/real
1570 wmodmax = m_zero
1571 do idim = 1, st%d%dim
1572 do ip = 1, mesh%np
1573 if(abs(real(zwn(ip, idim), real64)) >= 1e-2_real64) then
1574 wmodmax = max(wmodmax, abs(aimag(zwn(ip, idim)))/abs(real(zwn(ip, idim), real64)))
1575 end if
1576 end do
1577 end do
1578 call mesh_minmaxloc(mesh, wmodmax, rankmax, mpi_maxloc)
1579
1580 write(message(1), '(a,i4,a,f11.6)') 'oct-wannier90: Wannier function ', iw, ' Max. Im/Re Ratio = ', wmodmax
1581 call messages_info(1)
1582 end do
1583
1584 safe_deallocate_a(umnk)
1585 safe_deallocate_a(zwn)
1586 safe_deallocate_a(psi)
1587 safe_deallocate_a(phase)
1588 safe_deallocate_a(centers)
1589
1591 end subroutine generate_wannier_states
1592
1593end program wannier90_interface
1594
1595!! Local Variables:
1596!! mode: f90
1597!! coding: utf-8
1598!! End:
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
This module implements batches of mesh functions.
Definition: batch.F90:135
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
Definition: batch.F90:286
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
Definition: batch.F90:286
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
Definition: batch.F90:286
This module handles the calculation mode.
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
integer, parameter, public p_strategy_states
parallelization in states
subroutine, public zmesh_to_cube(mesh, mf, cube, cf)
Convert a function from the mesh to the cube.
subroutine, public dcube_function_free_rs(cube, cf)
Deallocates the real space grid.
subroutine, public zcube_function_alloc_rs(cube, cf, in_device, force_alloc)
Allocates locally the real space grid, if PFFT library is not used. Otherwise, it assigns the PFFT re...
subroutine, public cube_init(cube, nn, namespace, space, spacing, coord_system, fft_type, fft_library, dont_optimize, nn_out, mpi_grp, need_partition, tp_enlarge, blocksize)
Definition: cube.F90:204
subroutine, public cube_end(cube)
Definition: cube.F90:387
subroutine, public cube_init_cube_map(cube, mesh)
Definition: cube.F90:824
integer, parameter, public unpolarized
Parameters...
integer, parameter, public spinors
integer, parameter, public spin_polarized
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
Definition: fft.F90:120
subroutine, public fft_all_init(namespace)
initialize the table
Definition: fft.F90:269
subroutine, public fft_all_end()
delete all plans
Definition: fft.F90:380
real(real64), parameter, public m_two
Definition: global.F90:193
subroutine, public global_end()
Finalise parser varinfo file, and MPI.
Definition: global.F90:422
real(real64), parameter, public m_huge
Definition: global.F90:209
real(real64), parameter, public m_zero
Definition: global.F90:191
complex(real64), parameter, public m_z0
Definition: global.F90:201
complex(real64), parameter, public m_zi
Definition: global.F90:205
subroutine, public global_init(communicator)
Initialise Octopus.
Definition: global.F90:361
real(real64), parameter, public m_half
Definition: global.F90:197
real(real64), parameter, public m_one
Definition: global.F90:192
This module implements the underlying real-space grid.
Definition: grid.F90:119
Definition: io.F90:116
subroutine, public io_init(defaults)
If the argument defaults is present and set to true, then the routine will not try to read anything f...
Definition: io.F90:165
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
subroutine, public io_end()
Definition: io.F90:271
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
subroutine, public kpoints_to_absolute(latt, kin, kout)
Definition: kpoints.F90:1033
System information (time, memory, sysname)
Definition: loct.F90:117
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_end()
Definition: messages.F90:273
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1091
subroutine, public messages_init(output_dir)
Definition: messages.F90:220
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1063
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
type(namespace_t), public global_namespace
Definition: namespace.F90:134
subroutine, public orbitalset_init(this)
Definition: orbitalset.F90:208
subroutine, public orbitalset_end(this)
Definition: orbitalset.F90:234
subroutine, public orbitalset_update_phase(os, dim, kpt, kpoints, spin_polarized, vec_pot, vec_pot_var, kpt_max)
Build the phase correction to the global phase in case the orbital crosses the border of the simulato...
Definition: orbitalset.F90:284
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:455
subroutine, public parser_init()
Initialise the Octopus parser.
Definition: parser.F90:402
subroutine, public parser_end()
End the Octopus parser.
Definition: parser.F90:434
subroutine, public profiling_end(namespace)
Definition: profiling.F90:415
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
subroutine, public profiling_init(namespace)
Create profiling subdirectory.
Definition: profiling.F90:257
integer, parameter, public restart_gs
Definition: restart.F90:156
integer, parameter, public restart_td
Definition: restart.F90:156
integer, parameter, public restart_type_load
Definition: restart.F90:183
subroutine, public zstates_elec_rrqr_decomposition(st, namespace, mesh, nst, root, ik, jpvt)
Perform RRQR on the transpose states stored in the states object and return the pivot vector.
This module defines routines to write information about states.
logical function, public state_kpt_is_local(st, ist, ik)
check whether a given state (ist, ik) is on the local node
subroutine, public states_elec_allocate_wfns(st, mesh, wfs_type, skip, packed)
Allocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_look(restart, nik, dim, nst, ierr)
Reads the 'states' file in the restart directory, and finds out the nik, dim, and nst contained in it...
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_load(restart, namespace, space, st, mesh, kpoints, ierr, iter, lr, lowest_missing, label, verbose, skip)
returns in ierr: <0 => Fatal error, or nothing read =0 => read all wavefunctions >0 => could only rea...
subroutine, public submesh_init(this, space, mesh, latt, center, rc)
Definition: submesh.F90:282
type(type_t), public type_cmplx
Definition: types.F90:136
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
type(unit_t), public unit_angstrom
For XYZ files.
subroutine, public unit_system_init(namespace)
type(unit_t), public unit_ev
For output energies in eV.
This module is intended to contain simple general-purpose utility functions and procedures.
Definition: utils.F90:120
subroutine, public ylm_wannier(ylm, l, mr, rr, xx, nr)
Class describing the electron system.
Definition: electrons.F90:220
Describes mesh distribution to nodes.
Definition: mesh.F90:187
The states_elec_t class contains all electronic wave functions.
batches of electronic states
Definition: wfs_elec.F90:141
int true(void)
subroutine create_wannier90_spn(mesh, st)
Write the spn file containing .
subroutine create_wannier90_eig()
subroutine read_wannier90_files()
subroutine create_wannier90_mmn(mesh, st)
subroutine wannier90_setup(ions, kpoints, space)
subroutine write_unk(space, mesh, st)
subroutine generate_wannier_states(space, mesh, ions, st, kpoints)
program wannier90_interface
subroutine create_wannier90_amn(space, mesh, latt, st, kpoints)
subroutine wannier90_output()