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