37 use,
intrinsic :: iso_fortran_env
71 integer :: w90_what, w90_mode
72 integer(int64) :: w90_what_default
76 integer :: ii, nik, iter, nst
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
82 integer,
allocatable :: w90_nnk_list(:,:)
83 character(len=80) :: w90_prefix
84 integer :: w90_num_wann
85 real(real64),
allocatable :: w90_proj_centers(:,:)
86 integer,
allocatable :: w90_proj_lmr(:,:)
88 integer,
allocatable :: w90_spin_proj_component(:)
89 real(real64),
allocatable :: w90_spin_proj_axis(:,:)
90 integer :: w90_num_exclude
91 logical,
allocatable :: exclude_list(:)
92 integer,
allocatable :: band_index(:)
93 logical :: read_td_states
94 integer :: w90_spin_channel
97 integer,
allocatable :: jpvt(:)
98 complex(real64),
allocatable :: uk(:,:,:)
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
105 integer(int64) :: how
130 if (w90_prefix ==
'w90')
then
131 message(1) =
"oct-wannier90: the prefix is set by default to w90"
161 if (w90_mode == 0)
then
162 message(1) =
"Wannier90Mode must be set to a value different from 0."
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
226 if (sys%kpoints%use_symmetries)
then
227 message(1) =
'oct-wannier90: k-points symmetries are not allowed'
230 if (sys%kpoints%use_time_reversal)
then
231 message(1) =
'oct-wannier90: time-reversal symmetry is not allowed'
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'
244 w90_spinors = .false.
249 do idir = sys%space%periodic_dim+1, sys%space%dim
250 factor(idir) =
m_two * sys%gr%box%bounding_box_l(idir)
252 call sys%ions%latt%scale(factor)
255 select case (w90_mode)
256 case (option__wannier90mode__w90_setup)
260 case (option__wannier90mode__w90_output)
263 case (option__wannier90mode__w90_wannier)
268 if (read_td_states)
then
270 sys%mc, ierr, sys%gr)
273 sys%mc, ierr, sys%gr)
278 if (dim == sys%st%d%dim .and. nik == sys%kpoints%reduced%npoints .and. nst >= sys%st%nst)
then
280 ierr, iter, label =
": wannier90", skip=exclude_list)
282 write(
message(1),
'(a)')
'Restart structure not commensurate.'
290 message(1) =
"Wannier90Mode is set to an unsupported value."
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)
300 safe_deallocate_p(sys)
312 type(
ions_t),
intent(in) :: ions
314 class(
space_t),
intent(in) :: space
316 character(len=80) :: filename
317 integer :: w90_win, ia, axis(3), npath
321 assert(space%dim == 3)
324 filename = trim(adjustl(w90_prefix)) //
'.win'
327 write(w90_win,
'(a)')
'# this file has been created by the Octopus wannier90 utility'
328 write(w90_win,
'(a)')
' '
331 write(w90_win,
'(a)')
'begin unit_cell_cart'
332 write(w90_win,
'(a)')
'Ang'
336 write(w90_win,
'(a)')
'end unit_cell_cart'
337 write(w90_win,
'(a)')
' '
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))
343 write(w90_win,
'(a)')
'end atoms_frac'
344 write(w90_win,
'(a)')
' '
347 write(w90_win,
'(a)')
'use_bloch_phases = .true.'
348 write(w90_win,
'(a)')
' '
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)')
' '
354 if (sys%st%d%ispin ==
spinors)
then
355 write(w90_win,
'(a)')
'spinors = .true.'
358 write(w90_win,
'(a)')
'spin = up'
362 write(w90_win,
'(a)')
'write_u_matrices = .true.'
363 write(w90_win,
'(a)')
'write_xyz = .true.'
364 write(w90_win,
'(a)')
' '
366 if (kpoints%reduced%npoints == 1)
then
367 write(w90_win,
'(a)')
'gamma_only = .true.'
368 write(w90_win,
'(a)')
' '
371 message(1) =
'oct-wannier90: need Monkhorst-Pack grid. Please specify %KPointsGrid'
376 npath = kpoints%nkpt_in_path()
378 axis(1:3) = kpoints%nik_axis(1:3)
379 assert(product(kpoints%nik_axis(1:3)) == kpoints%reduced%npoints - npath)
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 '
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)
389 write(w90_win,
'(a)')
'end kpoints '
408 if (read_td_states)
then
410 sys%mc, ierr, sys%gr)
413 sys%mc, ierr, sys%gr)
421 if (dim == sys%st%d%dim .and. nik == sys%kpoints%reduced%npoints .and. nst >= sys%st%nst)
then
423 ierr, iter, label =
": wannier90", skip=exclude_list)
425 write(
message(1),
'(a)')
'Restart structure not commensurate.'
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))
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)
446 do ist = 1, w90_num_bands
447 sys%st%occ(ist, 1) = occ_temp(ist)
450 safe_allocate(uk(1:w90_num_bands, 1:w90_num_bands, 1:nik))
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))
458 chi(1:w90_num_bands, 1:w90_num_bands) =
m_zero
461 kvec(:) = sys%kpoints%reduced%point(:, ik)
464 ik_real = (ik-1)*2 + w90_spin_channel
469 do ist = 1, w90_num_bands
471 smear=
m_half *
loct_erfc((sys%st%eigenval(ist, ik_real) - scdm_mu) / scdm_sigma)
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)))
481 chi_diag = matmul(conjg(transpose(chi)), chi)
483 chi2 = conjg(transpose(chi_diag))
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'
493 do ist = 1, w90_num_bands
495 chi2(ist, 1:w90_num_bands) = chi_eigenval(ist) * chi2(ist, 1:w90_num_bands)
499 uk(:,:,ik) = matmul(chi, matmul(chi_diag,chi2))
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)
514 if (
bitand(w90_what, option__wannier90files__w90_mmn) /= 0)
then
518 if (
bitand(w90_what, option__wannier90files__w90_unk) /= 0)
then
519 call write_unk(sys%space, sys%gr, sys%st)
522 if (
bitand(w90_what, option__wannier90files__w90_amn) /= 0)
then
526 if (
bitand(w90_what, option__wannier90files__w90_eig) /= 0)
then
530 if (
bitand(w90_what, option__wannier90files__w90_spn) /= 0)
then
534 safe_deallocate_a(uk)
535 safe_deallocate_a(w90_spin_proj_component)
536 safe_deallocate_a(w90_spin_proj_axis)
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)
550 w90_num_kpts = product(sys%kpoints%nik_axis(1:3))
551 assert(w90_num_kpts == sys%st%nik)
557 filename = trim(adjustl(w90_prefix)) //
'.nnkp'
559 message(1) =
"oct-wannier90: Parsing "//filename
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.'
569 parse_is_ok = .false.
574 read(w90_nnkp, *, iostat=io) dummy, dummy1
575 if (io == iostat_end)
exit
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.'
590 if (.not. parse_is_ok)
then
591 message(1) =
'oct-wannier90: Did not find the kpoints block in nnkp file'
594 parse_is_ok = .false.
600 read(w90_nnkp, *, iostat=io) dummy, dummy1
601 if (io == iostat_end)
exit
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)
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.'
620 if (.not. parse_is_ok)
then
621 message(1) =
'oct-wannier90: Did not find nnkpts block in nnkp file'
627 safe_allocate(exclude_list(1:sys%st%nst))
629 exclude_list(1:sys%st%nst) = .false.
632 read(w90_nnkp, *, iostat=io) dummy, dummy1
633 if (io == iostat_end)
exit
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.'
642 exclude_list(itemp) = .
true.
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.'
656 w90_num_bands = sys%st%nst - w90_num_exclude
658 safe_allocate(band_index(1:sys%st%nst))
660 do ii = 1, sys%st%nst
661 if (exclude_list(ii)) cycle
663 band_index(ii) = itemp
666 if (
bitand(w90_what, option__wannier90files__w90_amn) /= 0 &
667 .or. w90_mode == option__wannier90mode__w90_wannier )
then
672 read(w90_nnkp, *, iostat=io) dummy, dummy1
673 if (io == iostat_end)
then
674 message(1) =
'oct-wannier90: Did not find projections block in w90.nnkp file'
678 if (dummy ==
'begin' .and. (dummy1 ==
'projections' .or. dummy1 ==
'spinor_projections'))
then
680 if (dummy1 ==
'spinor_projections')
then
682 if (sys%st%d%ispin /=
spinors)
then
683 message(1) =
'oct-wannier90: Spinor = .true. is only valid with spinors wavefunctions.'
687 message(1) =
'oct-wannier90: Spinor interface incomplete. Note there is no quantization axis implemented'
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.'
697 read(w90_nnkp, *) w90_nproj
700 w90_num_wann = w90_nproj
702 if(w90_nproj == 0) w90_num_wann = w90_num_bands
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))
709 if (w90_spinors)
then
710 safe_allocate(w90_spin_proj_axis(1:w90_nproj, 1:3))
714 read(w90_nnkp, *) w90_proj_centers(1:3, ii), w90_proj_lmr(ii, 1:3)
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)
720 if (w90_spin_proj_component(ii) == -1) w90_spin_proj_component(ii) = 2
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.'
736 read(w90_nnkp, *, iostat=io) dummy, dummy1
737 if (io == iostat_end)
exit
739 if (dummy ==
'begin' .and. dummy1 ==
'auto_projections')
then
741 read(w90_nnkp, *) w90_nproj
742 w90_num_wann = w90_nproj
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.'
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.'
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.'
766 message(1) =
"oct-wannier90: Finished parsing "//filename
771 filename = trim(adjustl(w90_prefix)) //
'.win'
772 message(1) =
"oct-wannier90: Parsing "//filename
776 read(w90_nnkp, fmt=
'(a)', iostat=io) line
777 if (io == iostat_end)
exit
778 if (index(line,
'=') > 0)
then
779 read(line, *, iostat=io) dummy, dummy2, dummy1
781 read(line, *, iostat=io) dummy, dummy1
785 if (dummy ==
'spin')
then
787 message(1) =
'oct-wannier90: The variable spin is set for a non spin-polarized calculation.'
791 if (dummy1 ==
'up')
then
793 else if (dummy1 ==
'down')
then
796 message(1) =
'oct-wannier90: Error parsing the variable spin.'
804 write(
message(1),
'(a,i1)')
'oct-wannier90: Using spin channel ', w90_spin_channel
808 message(1) =
"oct-wannier90: Finished parsing "//filename
817 class(
mesh_t),
intent(in) :: mesh
820 integer :: ist, jst, ik, ip, w90_mmn, iknn, idim, ibind
821 real(real64) :: Gcart(3)
823 character(len=80) :: filename
824 complex(real64),
allocatable :: overlap(:)
825 complex(real64),
allocatable :: psim(:,:), psin(:,:), phase(:)
827 integer :: inode, node_fr, node_to
828 type(mpi_request) :: send_req
834 if (st%parallel_in_states)
then
838 message(1) =
"Info: Computing the overlap matrix"
842 filename =
'./'// trim(adjustl(w90_prefix))//
'.mmn'
847 write(w90_mmn,*)
'Created by oct-wannier90'
848 write(w90_mmn,*) w90_num_bands, w90_num_kpts, w90_nntot
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))
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
866 ik = (ik-1)*2 + w90_spin_channel
867 iknn = (iknn-1)*2 + w90_spin_channel
872 if(ik >= st%d%kpt%start .and. ik <= st%d%kpt%end)
then
881 if (any(g /= 0))
then
883 phase(ip) =
exp(-
m_zi*dot_product(mesh%x(ip,1:3), gcart(1:3)))
891 if (exclude_list(jst)) cycle
894 if ( .not. st%d%kpt%parallel .and. .not. st%parallel_in_states)
then
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
903 if(ik >= st%st_kpt_task(inode,3) .and. ik <= st%st_kpt_task(inode,4))
then
910 send_req = mpi_request_null
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)
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)
923 if (send_req /= mpi_request_null)
then
924 call st%d%kpt%mpi_grp%wait(send_req)
930 if(ik >= st%d%kpt%start .and. ik <= st%d%kpt%end)
then
933 if (any(g /= 0))
then
935 do idim = 1, st%d%dim
937 psin(ip, idim) = psin(ip, idim) * phase(ip)
946 if (exclude_list(ist)) cycle
948 batch => st%group%psib(st%group%iblock(ist), ik)
950 select case (batch%status())
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.)
961 overlap(band_index(ist)) =
zmf_dotp(mesh, st%d%dim, psim, psin, reduce = .false.)
967 call mesh%allreduce(overlap)
970 if(st%d%kpt%parallel)
then
977 if (exclude_list(ist)) cycle
978 write(w90_mmn,
'(e18.10,2x,e18.10)') overlap(band_index(ist))
987 safe_deallocate_a(psim)
988 safe_deallocate_a(psin)
989 safe_deallocate_a(phase)
990 safe_deallocate_a(overlap)
1000 integer :: ist, ik, w90_eig
1001 character(len=80) :: filename
1005 if (sys%st%parallel_in_states)
then
1010 filename =
'./'//trim(adjustl(w90_prefix))//
'.eig'
1012 do ik = 1, w90_num_kpts
1013 do ist = 1, sys%st%nst
1014 if (exclude_list(ist)) cycle
1016 write(w90_eig,
'(I5,2x,I8,2x,e18.10)') band_index(ist), ik, &
1019 write(w90_eig,
'(I5,2x,I8,2x,e18.10)') band_index(ist), ik, &
1033 class(
space_t),
intent(in) :: space
1034 class(
mesh_t),
intent(in) :: mesh
1037 integer :: ist, ik, unk_file, ispin
1038 integer :: ix, iy, iz
1039 character(len=80) :: filename
1040 complex(real64),
allocatable :: psi(:)
1046 if (st%d%kpt%parallel)
then
1050 if (sys%gr%parallel_in_domains)
then
1054 if (st%parallel_in_states)
then
1061 safe_allocate(psi(1:mesh%np))
1064 mesh%coord_system, need_partition=.not.mesh%parallel_in_domains)
1069 do ik = 1, w90_num_kpts
1070 do ispin = 1, st%d%dim
1072 write(filename,
'(a,i5.5,a1,i1)')
'./UNK', ik,
'.', ispin
1075 write(unk_file) mesh%idx%ll(1:mesh%idx%dim), ik, w90_num_bands
1080 if (exclude_list(ist)) cycle
1090 if (cube%parallel_in_domains)
then
1091 assert(.not. cube%parallel_in_domains)
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))
1107 safe_deallocate_a(psi)
1115 class(
space_t),
intent(in) :: space
1116 class(
mesh_t),
intent(in) :: mesh
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(:)
1131 if (st%parallel_in_states)
then
1135 filename =
'./'// trim(adjustl(w90_prefix))//
'.amn'
1140 write(w90_amn,*)
'Created by oct-wannier90'
1141 write(w90_amn,*) w90_num_bands, w90_num_kpts, w90_num_wann
1146 message(1) =
"Info: Writing projections obtained from SCDM."
1149 if (st%d%kpt%parallel)
then
1154 do ik = 1, w90_num_kpts
1156 if (exclude_list(ist)) cycle
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)
1167 message(1) =
"Info: Computing the projection matrix"
1173 safe_allocate(orbitals(1:w90_nproj))
1178 orbitals(iw)%norbs = 1
1179 orbitals(iw)%ndim = 1
1180 orbitals(iw)%radius = -
log(threshold)
1181 orbitals(iw)%use_submesh = .false.
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)
1188 safe_allocate(ylm(1:orbitals(iw)%sphere%np))
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)
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))
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)
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
1212 kpt_max = w90_num_kpts)
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))
1220 do ik = 1, w90_num_kpts
1221 kpoint(1:space%dim) = kpoints%get_point(ik)
1223 phase(ip) =
exp(-
m_zi* sum(mesh%x(ip, 1:space%dim) * kpoint(1:space%dim)))
1228 ik_real = (ik-1)*2 + w90_spin_channel
1235 if (exclude_list(ist)) cycle
1239 if(ik_real >= st%d%kpt%start .and. ik_real <= st%d%kpt%end)
then
1242 do idim = 1, st%d%dim
1245 psi(ip, idim) = psi(ip, idim)*phase(ip)
1249 do iw = 1, w90_nproj
1251 if (w90_spinors) idim = w90_spin_proj_component(iw)
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.)
1260 call mesh%allreduce(projection)
1264 if(st%d%kpt%parallel)
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)
1276 safe_deallocate_a(psi)
1277 safe_deallocate_a(phase)
1278 safe_deallocate_a(projection)
1280 do iw = 1, w90_nproj
1283 safe_deallocate_a(orbitals)
1299 class(mesh_t),
intent(in) :: mesh
1300 type(states_elec_t),
target,
intent(in) :: st
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
1309 call profiling_in(
"W90_SPN")
1311 assert(st%d%ispin == spinors)
1313 if (st%parallel_in_states)
then
1314 call messages_not_implemented(
"w90_spn output with states parallelization")
1317 message(1) =
"Info: Computing the spin file"
1318 call messages_info(1)
1320 filename =
'./'// trim(adjustl(w90_prefix))//
'.spn'
1321 w90_spn = io_open(trim(filename), global_namespace, action=
'write')
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
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))
1335 do ik = st%d%kpt%start, st%d%kpt%end
1338 if (exclude_list(jst)) cycle
1340 call states_elec_get_state(st, mesh, jst, ik, psim)
1342 if (exclude_list(ist)) cycle
1344 counter = counter + 1
1346 call states_elec_get_state(st, mesh, ist, ik, psin)
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.)
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
1360 call profiling_in(
"W90_SPN_REDUCE")
1361 call mesh%allreduce(spin)
1363 if(st%d%kpt%parallel)
then
1364 call comm_allreduce(st%d%kpt%mpi_grp, spin)
1366 call profiling_out(
"W90_SPN_REDUCE")
1369 if (mpi_world%is_root())
then
1370 do ik = 1, w90_num_kpts
1373 if (exclude_list(jst)) cycle
1376 if (exclude_list(ist)) cycle
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)
1387 call io_close(w90_spn)
1389 safe_deallocate_a(psim)
1390 safe_deallocate_a(psin)
1391 safe_deallocate_a(spin)
1393 call profiling_out(
"W90_SPN")
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
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
1416 type(unit_t) :: fn_unit
1417 complex(real64) :: scal
1421 message(1) =
"oct-wannier90: Constructing the Wannier states from the U matrix."
1422 call messages_info(1)
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)
1431 w90_xyz = io_open(trim(trim(adjustl(w90_prefix))//
'_centres.xyz'), global_namespace, action=
'read')
1433 safe_allocate(centers(1:3, 1:w90_num_wann))
1437 do iw = 1, w90_num_wann
1438 read(w90_xyz, *) dum, centers(1:3, iw)
1440 centers(1:3, iw) = units_to_atomic(unit_angstrom, centers(1:3, iw))
1442 call io_close(w90_xyz)
1445 inquire(file=trim(trim(adjustl(w90_prefix))//
'_u_dis.mat'),exist=exist)
1447 message(1) =
'oct-wannier90: Calculation of Wannier states with disentanglement is not yet supported.'
1448 call messages_fatal(1)
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)
1457 w90_u_mat = io_open(trim(trim(adjustl(w90_prefix))//
'_u.mat'), global_namespace, action=
'read')
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)
1470 safe_allocate(umnk(1:w90_num_wann, 1:w90_num_wann, 1:w90_num_kpts))
1472 do ik = 1, w90_num_kpts
1477 read(w90_u_mat,
'(f15.10,sp,f15.10)') ((umnk(iw, iw2, ik), iw=1, w90_num_wann), iw2=1, w90_num_wann)
1480 call io_close(w90_u_mat)
1483 call parse_variable(global_namespace,
'OutputFormat', 0, how)
1485 message(1) =
"OutputFormat must be specified for outputing Wannier functions."
1486 call messages_fatal(1)
1489 call io_mkdir(
'wannier', global_namespace)
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
1500 do ik = 1, w90_num_kpts
1502 if (.not. (ik >= st%d%kpt%start .and. ik <= st%d%kpt%end)) cycle
1504 kpoint(1:space%dim) = kpoints%get_point(ik, absolute_coordinates=.
true.)
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)))
1515 if (exclude_list(iw2)) cycle
1517 if (st%d%ispin /= spin_polarized)
then
1518 call states_elec_get_state(st, mesh, iw2, ik, psi)
1520 call states_elec_get_state(st, mesh, iw2, (ik-1)*2+w90_spin_channel, psi)
1523 do idim = 1, st%d%dim
1525 zwn(ip, idim) = zwn(ip, idim) + umnk(band_index(iw2), iw, ik) * psi(ip, idim) * phase(ip)
1531 if(st%d%kpt%parallel)
then
1532 call comm_allreduce(st%d%kpt%mpi_grp, zwn)
1537 if (sys%st%d%ispin /= spinors)
then
1541 do idim = 1, st%d%dim
1543 wmod = real(zwn(ip, idim)*conjg(zwn(ip, idim)), real64)
1544 if (wmod > wmodmax)
then
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)
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
1563 write(fname,
'(a,i3.3,a4,i1)')
'wannier-', iw
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)
1571 do idim = 1, st%d%dim
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)))
1578 call mesh_minmaxloc(mesh, wmodmax, rankmax, mpi_maxloc)
1580 write(message(1),
'(a,i4,a,f11.6)')
'oct-wannier90: Wannier function ', iw,
' Max. Im/Re Ratio = ', wmodmax
1581 call messages_info(1)
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)
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.
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
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)
subroutine, public cube_end(cube)
subroutine, public cube_init_cube_map(cube, mesh)
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 ...
subroutine, public fft_all_init(namespace)
initialize the table
subroutine, public fft_all_end()
delete all plans
real(real64), parameter, public m_two
subroutine, public global_end()
Finalise parser varinfo file, and MPI.
real(real64), parameter, public m_huge
real(real64), parameter, public m_zero
complex(real64), parameter, public m_z0
complex(real64), parameter, public m_zi
subroutine, public global_init(communicator)
Initialise Octopus.
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
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...
subroutine, public io_close(iunit, grp)
subroutine, public io_end()
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
subroutine, public kpoints_to_absolute(latt, kin, kout)
System information (time, memory, sysname)
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_end()
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_init(output_dir)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_experimental(name, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
type(mpi_grp_t), public mpi_world
This module handles the communicators for the various parallelization strategies.
type(namespace_t), public global_namespace
subroutine, public orbitalset_init(this)
subroutine, public orbitalset_end(this)
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...
logical function, public parse_is_defined(namespace, name)
subroutine, public parser_init()
Initialise the Octopus parser.
subroutine, public parser_end()
End the Octopus parser.
subroutine, public profiling_end(namespace)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
subroutine, public profiling_init(namespace)
Create profiling subdirectory.
integer, parameter, public restart_gs
integer, parameter, public restart_td
integer, parameter, public restart_type_load
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)
type(type_t), public type_cmplx
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
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.
subroutine, public ylm_wannier(ylm, l, mr, rr, xx, nr)
Class describing the electron system.
Describes mesh distribution to nodes.
The states_elec_t class contains all electronic wave functions.
batches of electronic states
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()