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
45 use mesh_oct_m
48 use mpi_oct_m
52 use parser_oct_m
57 use space_oct_m
58 use string_oct_m
63 use types_oct_m
64 use unit_oct_m
66 use utils_oct_m
69
70 implicit none
71
72 integer :: w90_what, w90_mode
73 integer(int64) :: w90_what_default
74
75 integer :: ierr
76 integer :: dim, idim
77 integer :: ii, nik, iter, nst
78
79 type(restart_t) :: restart
80 type(electrons_t), pointer :: sys
81 logical :: w90_spinors, scdm_proj, w90_scdm
82 integer :: w90_nntot, w90_num_bands, w90_num_kpts ! w90 input parameters
83 integer, allocatable :: w90_nnk_list(:,:) !
84 character(len=80) :: w90_prefix ! w90 input file prefix
85 integer :: w90_num_wann ! input paramter
86 real(real64), allocatable :: w90_proj_centers(:,:) ! projections centers
87 integer, allocatable :: w90_proj_lmr(:,:) ! definitions for real valued Y_lm*R_r
88 integer :: w90_nproj ! number of such projections
89 integer, allocatable :: w90_spin_proj_component(:) ! up/down flag
90 real(real64), allocatable :: w90_spin_proj_axis(:,:) ! spin axis (not implemented)
91 integer :: w90_num_exclude
92 logical, allocatable :: exclude_list(:) ! list of excluded bands
93 integer, allocatable :: band_index(:) ! band index after exclusion
94 logical :: read_td_states
95 integer :: w90_spin_channel
96 logical :: w90_bloch_sums = .false.
97
98 ! scdm variables
99 integer, allocatable :: jpvt(:)
100 complex(real64), allocatable :: uk(:,:,:) ! SCDM-Wannier gauge matrices U(k)
101 complex(real64), allocatable :: psi(:,:)
102 complex(real64), allocatable :: chi(:,:), chi_diag(:,:),chi2(:,:)
103 real(real64), allocatable :: chi_eigenval(:), occ_temp(:)
104 real(real64) :: scdm_mu, scdm_sigma, smear, kvec(3), factor(3)
105 integer :: ist, jst, ik, idir, sender
106
107 integer(int64) :: how
108
109 call global_init()
110 call parser_init()
111
112 call messages_init()
113 call io_init()
114
119
120 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
121 sys => electrons_t(global_namespace, int(option__calculationmode__dummy, int32))
122 call sys%init_parallelization(mpi_world)
123
124 !%Variable Wannier90Prefix
125 !%Type string
126 !%Default w90
127 !%Section Utilities::oct-wannier90
128 !%Description
129 !% Prefix for wannier90 files
130 !%End
131 call parse_variable(global_namespace, 'Wannier90Prefix', 'w90', w90_prefix)
132 if (w90_prefix == 'w90') then
133 message(1) = "oct-wannier90: the prefix is set by default to w90"
134 call messages_info(1)
135 end if
136
137 !%Variable Wannier90Mode
138 !%Type integer
139 !%Default 0
140 !%Section Utilities::oct-wannier90
141 !%Description
142 !% Specifies which stage of the Wannier90 interface to use
143 !%Option none 0
144 !% Nothing is done.
145 !%Option w90_setup 1
146 !% Writes parts of the wannier90 input file <tt>w90_prefix.win</tt> corresponding to
147 !% the octopus inp file. Importantly it generates the correct form of Monkhorst-Pack mesh
148 !% written to the file w90_kpoints that has to be used in a gs calculation of Octopus by
149 !% as <tt> include w90_kpoints </tt> instead of the <tt>%KpointsGrid</tt> block.
150 !%Option w90_output 2
151 !% Generates the relevant files for a wannier90 run, specified by the variable <tt>W90_interface_files</tt>.
152 !% This needs files previously generated
153 !% by <tt>wannier90.x -pp w90 </tt>
154 !%Option w90_wannier 3
155 !% Parse the output of wannier90 to generate the Wannier states on the real-space grid.
156 !% The states will be written in the folder wannier. By default, the states are written as
157 !% binary files, similar to the Kohn-Sham states.
158 !%
159 !% Not implemented for spinor states.
160 !%End
161 call parse_variable(global_namespace, 'Wannier90Mode', 0, w90_mode)
162
163 if (w90_mode == 0) then
164 message(1) = "Wannier90Mode must be set to a value different from 0."
165 call messages_fatal(1)
166 end if
167
168 !%Variable Wannier90Files
169 !%Type flag
170 !%Default w90_mmn + w90_amn + w90_eig
171 !%Section Utilities::oct-wannier90
172 !%Description
173 !% Specifies which files to generate.
174 !% Example: <tt>w90_mmn + w90_unk</tt>
175 !%Option w90_mmn bit(1)
176 !% (see Wannier90 documentation)
177 !%Option w90_unk bit(2)
178 !% (see Wannier90 documentation)
179 !%Option w90_amn bit(3)
180 !% (see Wannier90 documentation)
181 !%Option w90_eig bit(4)
182 !% Eigenvalues. See Wannier90 documentation for more details.
183 !%Option w90_spn bit(5)
184 !% Spin. See Wannier90 documentation for more details.
185 !%End
186 w90_what_default = option__wannier90files__w90_mmn + option__wannier90files__w90_amn + option__wannier90files__w90_eig
187 if (sys%st%d%ispin == spinors) w90_what_default = w90_what_default + option__wannier90files__w90_spn
188 call parse_variable(global_namespace, 'Wannier90Files', w90_what_default, w90_what)
189
190 !%Variable Wannier90UseTD
191 !%Type logical
192 !%Default no
193 !%Section Utilities::oct-wannier90
194 !%Description
195 !% By default oct-wannier90 uses the ground-state states to compute the necessary information.
196 !% By setting this variable to yes, oct-wannier90 will use the TD states instead.
197 !%End
198 call parse_variable(global_namespace, 'Wannier90UseTD', .false., read_td_states)
199
200 !%Variable Wannier90UseSCDM
201 !%Type logical
202 !%Default no
203 !%Section Utilities::oct-wannier90
204 !%Description
205 !% By default oct-wannier90 uses the projection method to generate the .amn file.
206 !% By setting this variable to yes, oct-wannier90 will use SCDM method instead.
207 !%End
208 call parse_variable(global_namespace, 'Wannier90UseSCDM', .false., w90_scdm)
209 if (w90_scdm) then
210 !%Variable SCDMsigma
211 !%Type float
212 !%Default 0.2
213 !%Section Utilities::oct-wannier90
214 !%Description
215 !% Broadening of SCDM smearing function.
216 !%End
217 call parse_variable(global_namespace, 'SCDMsigma', 0.2_real64, scdm_sigma)
218
219 !%Variable SCDMmu
220 !%Type float
221 !%Section Utilities::oct-wannier90
222 !%Description
223 !% Energy range up to which states are considered for SCDM.
224 !%End
225 call parse_variable(global_namespace, 'SCDMmu', m_huge, scdm_mu)
226 end if
227
228 if (sys%kpoints%use_symmetries) then
229 message(1) = 'oct-wannier90: k-points symmetries are not allowed'
230 call messages_fatal(1)
231 end if
232 if (sys%kpoints%use_time_reversal) then
233 message(1) = 'oct-wannier90: time-reversal symmetry is not allowed'
234 call messages_fatal(1)
235 end if
236 if (sys%kpoints%reduced%nshifts > 1) then
237 message(1) = 'oct-wannier90: Wannier90 does not allow for multiple shifts of the k-point grid'
238 call messages_fatal(1)
239 end if
240
241 if (sys%st%d%ispin /= unpolarized) then
242 call messages_experimental("oct-wannier90 with SpinComponnents /= unpolarized")
243 end if
244
245 w90_spinors = .false.
246
247 !%Variable Wannier90SpinChannel
248 !%Type integer
249 !%Section Utilities::oct-wannier90
250 !%Description
251 !% Spin channel used for the Wannierization
252 !%End
253 call parse_variable(global_namespace, 'Wannier90SpinChannel', 1, w90_spin_channel)
254
255 ! "Correct" rlattice/klattice for Wannier90 (3D periodicity assumed here).
256 factor = m_one
257 do idir = sys%space%periodic_dim+1, sys%space%dim
258 factor(idir) = m_two * sys%gr%box%bounding_box_l(idir)
259 end do
260 call sys%ions%latt%scale(factor)
261
262 ! create setup files
263 select case (w90_mode)
264 case (option__wannier90mode__w90_setup)
265 call wannier90_setup(sys%ions, sys%kpoints, sys%space)
266
267 ! load states and calculate interface files
268 case (option__wannier90mode__w90_output)
269 call wannier90_output()
270
271 case (option__wannier90mode__w90_wannier)
272 !%Variable Wannier90ComputeBlochSums
273 !%Type logical
274 !%Default no
275 !%Section Utilities::oct-wannier90
276 !%Description
277 !% Only for Wannier90Mode = w90_wannier
278 !% By setting this variable to yes, oct-wannier90 will also output the Bloch sums
279 !% of the Wannier orbitals. This creates one file per k-point.
280 !%End
281 call parse_variable(global_namespace, 'Wannier90ComputeBlochSums', .false., w90_bloch_sums)
282
284
285 ! normal interface run
286 call states_elec_allocate_wfns(sys%st, sys%gr, wfs_type = type_cmplx, skip=exclude_list)
287 if (read_td_states) then
288 call restart%init(global_namespace, restart_td, restart_type_load, &
289 sys%mc, ierr, sys%gr)
290 else
291 call restart%init(global_namespace, restart_gs, restart_type_load, &
292 sys%mc, ierr, sys%gr)
293 end if
294
295 if (ierr == 0) then
296 call states_elec_look(restart, nik, dim, nst, ierr)
297 if (sys%st%d%ispin == spin_polarized) then
298 nik = nik / 2
299 end if
300 if (dim == sys%st%d%dim .and. nik == sys%kpoints%reduced%npoints .and. nst >= sys%st%nst) then
301 call states_elec_load(restart, global_namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
302 ierr, iter, label = ": wannier90", skip=exclude_list)
303 else
304 write(message(1),'(a)') 'Restart structure not commensurate.'
305 call messages_fatal(1)
306 end if
307 end if
308 call restart%end()
309
310 call generate_wannier_states(sys%space, sys%gr, sys%ions, sys%st, sys%kpoints)
311 case default
312 message(1) = "Wannier90Mode is set to an unsupported value."
313 call messages_fatal(1)
314 end select
315
316 safe_deallocate_a(exclude_list)
317 safe_deallocate_a(band_index)
318 safe_deallocate_a(w90_nnk_list)
319 safe_deallocate_a(w90_proj_centers)
320 safe_deallocate_a(w90_proj_lmr)
321
322 safe_deallocate_p(sys)
323 call fft_all_end()
324 call io_end()
326 call messages_end()
327 call parser_end()
328 call global_end()
329
330contains
331
332 ! --------------------------------------------------------------------------
333 subroutine wannier90_setup(ions, kpoints, space)
334 type(ions_t), intent(in) :: ions
335 type(kpoints_t), intent(in) :: kpoints
336 class(space_t), intent(in) :: space
337
338 character(len=80) :: filename
339 integer :: w90_win, ia, axis(3), npath
340
341 push_sub(wannier90_setup)
342
343 assert(space%dim == 3)
344
345 ! open win file
346 filename = trim(adjustl(w90_prefix)) //'.win'
347 w90_win = io_open(trim(filename), global_namespace, action='write')
348
349 write(w90_win,'(a)') '# this file has been created by the Octopus wannier90 utility'
350 write(w90_win,'(a)') ' '
351
352 ! write direct lattice vectors (in angstrom)
353 write(w90_win,'(a)') 'begin unit_cell_cart'
354 write(w90_win,'(a)') 'Ang'
355 do idim = 1,3
356 write(w90_win,'(f13.8,f13.8,f13.8)') units_from_atomic(unit_angstrom, ions%latt%rlattice(1:3,idim))
357 end do
358 write(w90_win,'(a)') 'end unit_cell_cart'
359 write(w90_win,'(a)') ' '
360
361 write(w90_win,'(a)') 'begin atoms_frac'
362 do ia = 1, ions%natoms
363 write(w90_win,'(a,2x,f13.8,f13.8,f13.8)') trim(ions%atom(ia)%label), ions%latt%cart_to_red(ions%pos(:, ia))
364 end do
365 write(w90_win,'(a)') 'end atoms_frac'
366 write(w90_win,'(a)') ' '
367
368 ! This is a default value. In practice, one should use projections
369 write(w90_win,'(a)') 'use_bloch_phases = .true.'
370 write(w90_win,'(a)') ' '
371
372 write(w90_win,'(a10,i4)') 'num_bands ', sys%st%nst
373 write(w90_win,'(a9,i4)') 'num_wann ', sys%st%nst
374 write(w90_win,'(a)') ' '
375
376 if (sys%st%d%ispin == spinors) then
377 write(w90_win,'(a)') 'spinors = .true.'
378 end if
379 if (sys%st%d%ispin == spin_polarized) then
380 if (w90_spin_channel == 1) then
381 write(w90_win, '(a)') 'spin = up'
382 else if (w90_spin_channel == 2) then
383 write(w90_win, '(a)') 'spin = down'
384 else
385 message(1) = 'Wannier90SpinChannel value is invalid.'
386 call messages_fatal(1)
387 end if
388 end if
389
390 ! This is for convenience. This is needed for plotting the Wannier states, if requested.
391 write(w90_win,'(a)') 'write_u_matrices = .true.'
392 write(w90_win,'(a)') 'write_xyz = .true.'
393 write(w90_win,'(a)') ' '
394
395 if (kpoints%reduced%npoints == 1) then
396 write(w90_win,'(a)') 'gamma_only = .true.'
397 write(w90_win,'(a)') ' '
398 else
399 if (.not. parse_is_defined(global_namespace, 'KPointsGrid')) then
400 message(1) = 'oct-wannier90: need Monkhorst-Pack grid. Please specify %KPointsGrid'
401 call messages_fatal(1)
402 end if
403
404 ! In case the user used also a k-point path, we ignore it
405 npath = kpoints%nkpt_in_path()
406
407 axis(1:3) = kpoints%nik_axis(1:3)
408 assert(product(kpoints%nik_axis(1:3)) == kpoints%reduced%npoints - npath)
409
410 write(w90_win,'(a8,i4,i4,i4)') 'mp_grid =', axis(1:3)
411 write(w90_win,'(a)') ' '
412 write(w90_win,'(a)') 'begin kpoints '
413 ! Put a minus sign here for the wrong convention in Octopus
414
415 do ii = 1, kpoints%reduced%npoints-npath
416 write(w90_win,'(f13.8,f13.8,f13.8)') - kpoints%reduced%red_point(1:3,ii)
417 end do
418 write(w90_win,'(a)') 'end kpoints '
419 end if
420
421 call io_close(w90_win)
422
423 pop_sub(wannier90_setup)
424
425 end subroutine wannier90_setup
426
427 ! --------------------------------------------------------------------------
428 subroutine wannier90_output()
429 integer :: ik_real
430
431 push_sub(wannier90_output)
432
434
435 ! normal interface run
436 call states_elec_allocate_wfns(sys%st, sys%gr, wfs_type = type_cmplx, skip=exclude_list)
437 if (read_td_states) then
438 call restart%init(global_namespace, restart_td, restart_type_load, &
439 sys%mc, ierr, sys%gr)
440 else
441 call restart%init(global_namespace, restart_gs, restart_type_load, &
442 sys%mc, ierr, sys%gr)
443 end if
444
445 if (ierr == 0) then
446 call states_elec_look(restart, nik, dim, nst, ierr)
447 if (sys%st%d%ispin == spin_polarized) then
448 nik = nik / 2
449 end if
450 if (dim == sys%st%d%dim .and. nik == sys%kpoints%reduced%npoints .and. nst >= sys%st%nst) then
451 call states_elec_load(restart, global_namespace, sys%space, sys%st, sys%gr, sys%kpoints, &
452 ierr, iter, label = ": wannier90", skip=exclude_list)
453 else
454 write(message(1),'(a)') 'Restart structure not commensurate.'
455 call messages_fatal(1)
456 end if
457 end if
458 call restart%end()
459
460 if (w90_scdm) then
461 nik = w90_num_kpts
462 safe_allocate(jpvt(1:sys%gr%np_global*sys%st%d%dim))
463 safe_allocate(psi(1:sys%gr%np, 1:sys%st%d%dim))
464 safe_allocate(occ_temp(1:w90_num_bands))
465
466 ! smear the states at gamma
467 do ist = 1, w90_num_bands
468 occ_temp(ist)= sys%st%occ(ist, 1)
469 sys%st%occ(ist, 1)=m_half*erfc((sys%st%eigenval(ist, 1)-scdm_mu) / scdm_sigma)
470 end do
471
472 call zstates_elec_rrqr_decomposition(sys%st, sys%namespace, sys%gr, w90_num_bands, .true., 1, jpvt)
473
474 ! reset occupations at gamma
475 do ist = 1, w90_num_bands
476 sys%st%occ(ist, 1) = occ_temp(ist)
477 end do
478
479 safe_allocate(uk(1:w90_num_bands, 1:w90_num_bands, 1:nik))
480
481 ! auxiliary arrays for scdm procedure
482 safe_allocate(chi(1:w90_num_bands, 1:w90_num_bands))
483 safe_allocate(chi_diag(1:w90_num_bands, 1:w90_num_bands))
484 safe_allocate(chi2(1:w90_num_bands, 1:w90_num_bands))
485 safe_allocate(chi_eigenval(1:w90_num_bands))
486
487 chi(1:w90_num_bands, 1:w90_num_bands) = m_zero
488
489 do ik = 1, nik
490 kvec(:) = sys%kpoints%reduced%point(:, ik)
491
492 if (sys%st%d%ispin == spin_polarized) then
493 ik_real = (ik-1)*2 + w90_spin_channel
494 else
495 ik_real = ik
496 end if
497
498 do ist = 1, w90_num_bands
499 sender = -1
500 if (state_kpt_is_local(sys%st, ist, ik_real)) then
501 call states_elec_get_state(sys%st, sys%gr, ist, ik_real, psi)
502 sender = sys%st%d%kpt%mpi_grp%rank
503 endif
504 call sys%st%d%kpt%mpi_grp%allreduce_inplace(sender, 1, mpi_integer, mpi_max)
505 assert(sender >= 0)
506 call sys%st%d%kpt%mpi_grp%bcast(psi, sys%gr%np*sys%st%d%dim, mpi_double_complex, sender)
507 smear=m_half * erfc((sys%st%eigenval(ist, ik_real) - scdm_mu) / scdm_sigma)
508 ! NOTE: here check for domain parallelization
509 do jst = 1, w90_num_bands
510 chi(ist, jst) = smear * conjg(psi(jpvt(jst), 1)) &
511 * exp(m_zi * dot_product(sys%gr%x(1:3, jpvt(jst)), kvec(1:3)))
512 end do
513 end do
514
515 ! loewdin orhtogonalization of chi.chi
516 ! this can also be done with SVD, which might be more stable!?
517 chi_diag = matmul(conjg(transpose(chi)), chi)
518 call lalg_eigensolve(w90_num_bands, chi_diag, chi_eigenval)
519 chi2 = conjg(transpose(chi_diag))
520
521 !we need the eigenvalues to be >0
522 if (any(chi_eigenval(:) .lt. m_zero)) then
523 message(1) = 'SCDM Wannierization failed because chi matrix is'
524 message(2) = 'ill conditioned. Try increasingin scdm_sigma and/or'
525 message(3) = 'change scdm_mu.'
526 call messages_fatal(3)
527 end if
528
529 do ist = 1, w90_num_bands
530 chi_eigenval(ist) = m_one / sqrt(chi_eigenval(ist))
531 chi2(ist, 1:w90_num_bands) = chi_eigenval(ist) * chi2(ist, 1:w90_num_bands)
532 end do
533 ! the loewdin result would be: matmul(chi_diag,chi2)
534 ! to get the wannier gauge U(k) we multiply this with the original chi
535 uk(:,:,ik) = matmul(chi, matmul(chi_diag,chi2))
536
537 end do
538
539 safe_deallocate_a(chi)
540 safe_deallocate_a(psi)
541 safe_deallocate_a(chi_diag)
542 safe_deallocate_a(chi2)
543 safe_deallocate_a(chi_eigenval)
544 safe_deallocate_a(jpvt)
545 safe_deallocate_a(psi)
546 safe_deallocate_a(occ_temp)
547 end if
548
549 ! ---- actual interface work ----------
550 if (bitand(w90_what, option__wannier90files__w90_mmn) /= 0) then
551 call create_wannier90_mmn(sys%gr, sys%st)
552 end if
553
554 if (bitand(w90_what, option__wannier90files__w90_unk) /= 0) then
555 call write_unk(sys%space, sys%gr, sys%st, formatted=.false.)
556 end if
557
558 if (bitand(w90_what, option__wannier90files__w90_amn) /= 0) then
559 call create_wannier90_amn(sys%space, sys%gr, sys%ions%latt, sys%st, sys%kpoints)
560 end if
561
562 if (bitand(w90_what, option__wannier90files__w90_eig) /= 0) then
564 end if
565
566 if (bitand(w90_what, option__wannier90files__w90_spn) /= 0) then
567 call create_wannier90_spn(sys%gr, sys%st)
568 end if
569
570 safe_deallocate_a(uk)
571 safe_deallocate_a(w90_spin_proj_component)
572 safe_deallocate_a(w90_spin_proj_axis)
573
574 pop_sub(wannier90_output)
575 end subroutine wannier90_output
576
577 ! --------------------------------------------------------------------------
578 subroutine read_wannier90_files()
579 integer :: w90_nnkp, itemp, dummyint, io, spin_channel_win
580 character(len=80) :: filename, dummy, dummy1, dummy2, line
581 logical :: exist, parse_is_ok
582 real(real64) :: dummyr(7)
583
584 push_sub(read_wannier90_files)
585
586 w90_num_kpts = product(sys%kpoints%nik_axis(1:3))
587 assert(w90_num_kpts == sys%st%nik)
588
589
590 w90_num_exclude = 0
591
592 ! open nnkp file
593 filename = trim(adjustl(w90_prefix)) //'.nnkp'
594
595 message(1) = "oct-wannier90: Parsing "//filename
596 call messages_info(1)
597
598 inquire(file=filename,exist=exist)
599 if (.not. exist) then
600 message(1) = 'oct-wannier90: Cannot find specified Wannier90 nnkp file.'
601 write(message(2),'(a)') 'Please run wannier90.x -pp '// trim(adjustl(w90_prefix)) // ' first.'
602 call messages_fatal(2)
603 end if
604
605 parse_is_ok = .false.
606
607 ! check number of k-points
608 w90_nnkp = io_open(trim(filename), global_namespace, action='read')
609 do
610 read(w90_nnkp, *, iostat=io) dummy, dummy1
611 if (io == iostat_end) exit
612
613 if (dummy == 'begin' .and. dummy1 == 'kpoints') then
614 read(w90_nnkp,*) itemp
615 if (itemp /= w90_num_kpts) then
616 message(1) = 'oct-wannier90: wannier90 setup seems to have been done with a different number of k-points.'
617 call messages_fatal(1)
618 else
619 parse_is_ok = .true.
620 exit
621 end if
622 end if
623 end do
624 call io_close(w90_nnkp)
625
626 if (.not. parse_is_ok) then
627 message(1) = 'oct-wannier90: Did not find the kpoints block in nnkp file'
628 call messages_fatal(1)
629 end if
630 parse_is_ok = .false.
631
632 ! read from nnkp file
633 ! find the nnkpts block
634 w90_nnkp = io_open(trim(filename), global_namespace, action='read', position='rewind')
635 do
636 read(w90_nnkp, *, iostat=io) dummy, dummy1
637 if (io == iostat_end) exit !End of file
638
639 if (dummy == 'begin' .and. dummy1 == 'nnkpts') then
640 read(w90_nnkp,*) w90_nntot
641 safe_allocate(w90_nnk_list(1:5, 1:w90_num_kpts * w90_nntot))
642 do ii = 1, w90_num_kpts * w90_nntot
643 read(w90_nnkp,*) w90_nnk_list(1:5, ii)
644 end do
645 !make sure we are at the end of the block
646 read(w90_nnkp,*) dummy
647 if (dummy /= 'end') then
648 message(1) = 'oct-wannier90: There dont seem to be enough k-points in nnkpts file to.'
649 call messages_fatal(1)
650 end if
651 parse_is_ok = .true.
652 exit
653 end if
654 end do
655
656 if (.not. parse_is_ok) then
657 message(1) = 'oct-wannier90: Did not find nnkpts block in nnkp file'
658 call messages_fatal(1)
659 end if
660
661 ! read from nnkp file
662 ! find the exclude block
663 safe_allocate(exclude_list(1:sys%st%nst))
664 !By default we use all the bands
665 exclude_list(1:sys%st%nst) = .false.
666 rewind(w90_nnkp)
667 do
668 read(w90_nnkp, *, iostat=io) dummy, dummy1
669 if (io == iostat_end) exit !End of file
670 if (dummy == 'begin' .and. dummy1 == 'exclude_bands') then
671 read(w90_nnkp, *) w90_num_exclude
672 do ii = 1, w90_num_exclude
673 read(w90_nnkp, *) itemp
674 if(itemp > sys%st%nst) then
675 message(1) = 'oct-wannier90: The exclude_bands list contains a state index higher than the number of states.'
676 call messages_fatal(1)
677 end if
678 exclude_list(itemp) = .true.
679 end do
680 !make sure we are at the end of the block
681 read(w90_nnkp, *) dummy
682 if (dummy /= 'end') then
683 message(1) = 'oct-wannier90: There dont seem to be enough bands in exclude_bands list.'
684 call messages_fatal(1)
685 end if
686 exit
687 end if
688 end do
689 call io_close(w90_nnkp)
690
691 !We get the number of bands
692 w90_num_bands = sys%st%nst - w90_num_exclude
693
694 safe_allocate(band_index(1:sys%st%nst))
695 itemp = 0
696 do ii = 1, sys%st%nst
697 if (exclude_list(ii)) cycle
698 itemp = itemp + 1
699 band_index(ii) = itemp
700 end do
701
702 if (bitand(w90_what, option__wannier90files__w90_amn) /= 0 &
703 .or. w90_mode == option__wannier90mode__w90_wannier ) then
704 ! parse file again for definitions of projections
705 w90_nnkp = io_open(trim(filename), global_namespace, action='read', position='rewind')
706
707 do
708 read(w90_nnkp, *, iostat=io) dummy, dummy1
709 if (io == iostat_end) then !End of file
710 message(1) = 'oct-wannier90: Did not find projections block in w90.nnkp file'
711 call messages_fatal(1)
712 end if
713
714 if (dummy == 'begin' .and. (dummy1 == 'projections' .or. dummy1 == 'spinor_projections')) then
715
716 if (dummy1 == 'spinor_projections') then
717 w90_spinors = .true.
718 if (sys%st%d%ispin /= spinors) then
719 message(1) = 'oct-wannier90: Spinor = .true. is only valid with spinors wavefunctions.'
720 call messages_fatal(1)
721 end if
722
723 message(1) = 'oct-wannier90: Spinor interface incomplete. Note there is no quantization axis implemented'
724 call messages_warning(1)
725 else
726 if (sys%st%d%ispin == spinors) then
727 message(1) = 'oct-wannier90: Octopus has spinors wavefunctions but spinor_projections is not defined.'
728 message(2) = 'oct-wannier90: Please check the input file for wannier 90.'
729 call messages_fatal(2)
730 end if
731 end if
732
733 read(w90_nnkp, *) w90_nproj
734 ! num_wann is given in w90.win, not double checked here
735 ! I assume that the wannier90.x -pp run has checked this
736 w90_num_wann = w90_nproj
737 ! In case of no projections, we use the number of bands
738 if(w90_nproj == 0) w90_num_wann = w90_num_bands
739
740 safe_allocate(w90_proj_centers(1:3, 1:w90_nproj))
741 safe_allocate(w90_proj_lmr(1:w90_nproj, 1:3))
742 if (w90_spinors) then
743 safe_allocate(w90_spin_proj_component(1:w90_nproj))
744 end if
745 if (w90_spinors) then
746 safe_allocate(w90_spin_proj_axis(1:w90_nproj, 1:3))
747 end if
748
749 do ii = 1, w90_nproj
750 read(w90_nnkp, *) w90_proj_centers(1:3, ii), w90_proj_lmr(ii, 1:3)
751 ! skip a line for now
752 read(w90_nnkp, *) dummyr(1:7)
753 if (w90_spinors) then
754 read(w90_nnkp, *) w90_spin_proj_component(ii), w90_spin_proj_axis(ii, 1:3)
755 ! use octopus spindim conventions
756 if (w90_spin_proj_component(ii) == -1) w90_spin_proj_component(ii) = 2
757 end if
758 end do
759 !make sure we are at the end of the block
760 read(w90_nnkp, *) dummy
761 if (dummy /= 'end') then
762 message(1) = 'oct-wannier90: There dont seem to be enough projections in nnkpts file to.'
763 call messages_fatal(1)
764 end if
765 exit
766 end if
767 end do
768
769 ! look for auto_projection block
770 scdm_proj = .false.
771 do
772 read(w90_nnkp, *, iostat=io) dummy, dummy1
773 if (io == iostat_end) exit !End of file
774
775 if (dummy == 'begin' .and. dummy1 == 'auto_projections') then
776 scdm_proj = .true.
777 read(w90_nnkp, *) w90_nproj
778 w90_num_wann = w90_nproj
779
780 if (.not. w90_scdm) then
781 message(1) = 'oct-wannier90: Found auto_projections block. Currently the only implemented automatic way'
782 message(2) = 'oct-wannier90: to compute projections is the SCDM method.'
783 message(3) = 'oct-wannier90: Please set Wannier90UseSCDM = yes in the inp file.'
784 call messages_fatal(3)
785 end if
786
787 if (w90_nproj /= w90_num_bands) then
788 message(1) = 'oct-wannier90: In auto_projections block first row needs to be equal to num_bands.'
789 call messages_fatal(1)
790 end if
791 read(w90_nnkp, *) dummyint
792 if (dummyint /= 0) then
793 message(1) = 'oct-wannier90: The second row in auto_projections has to be 0, per Wannier90 documentation.'
794 call messages_fatal(1)
795 end if
796 end if
797 end do
798 call io_close(w90_nnkp)
799
800 end if
801
802 message(1) = "oct-wannier90: Finished parsing "//filename
803 call messages_info(1)
804
805 ! Look extra variables variable
806 ! open win file
807 filename = trim(adjustl(w90_prefix)) //'.win'
808 message(1) = "oct-wannier90: Parsing "//filename
809 call messages_info(1)
810 w90_nnkp = io_open(trim(filename), global_namespace, action='read', position='rewind')
811 do
812 read(w90_nnkp, fmt='(a)', iostat=io) line
813 if (io == iostat_end) exit !End of file
814 if (index(line, '=') > 0) then
815 read(line, *, iostat=io) dummy, dummy2, dummy1
816 else
817 read(line, *, iostat=io) dummy, dummy1
818 end if
819
820 !Spin
821 if (dummy == 'spin') then
822 if (sys%st%d%ispin /= spin_polarized) then
823 message(1) = 'oct-wannier90: The variable spin is set for a non spin-polarized calculation.'
824 call messages_fatal(1)
825 end if
826
827 if (dummy1 == 'up') then
828 spin_channel_win = 1
829 else if (dummy1 == 'down') then
830 spin_channel_win = 2
831 else
832 message(1) = 'oct-wannier90: Error parsing the variable spin.'
833 call messages_fatal(1)
834 end if
835 if (spin_channel_win /= w90_spin_channel) then
836 message(1) = 'spin polarization input from .win and Wannier90SpinChannel do not agree.'
837 call messages_fatal(1)
838 end if
839 end if
840 end do
841 call io_close(w90_nnkp)
842
843 if (sys%st%d%ispin == spin_polarized) then
844 write(message(1), '(a,i1)') 'oct-wannier90: Using spin channel ', w90_spin_channel
845 call messages_info(1)
846 end if
847
848 message(1) = "oct-wannier90: Finished parsing "//filename
849 call messages_info(1)
850
851 pop_sub(read_wannier90_files)
852
853 end subroutine read_wannier90_files
854
855 ! --------------------------------------------------------------------------
856 subroutine create_wannier90_mmn(mesh, st)
857 class(mesh_t), intent(in) :: mesh
858 type(states_elec_t), target, intent(in) :: st
859
860 integer :: ist, jst, ik, ip, w90_mmn, iknn, ib
861 real(real64) :: Gcart(3)
862 integer :: G(3)
863 character(len=80) :: filename
864 complex(real64), allocatable :: overlap(:), ss(:)
865 complex(real64), allocatable :: psin(:,:), phase(:)
866 type(wfs_elec_t), pointer :: batch
867 integer :: inode, node_fr, node_to
868 type(mpi_request) :: send_req
869
870 push_sub(create_wannier90_mmn)
871
872 call profiling_in("W90_MMN")
873
874 if (st%parallel_in_states) then
875 call messages_not_implemented("w90_mmn output with states parallelization")
876 end if
877
878 message(1) = "Info: Computing the overlap matrix"
879 call messages_info(1)
880
881
882 filename = './'// trim(adjustl(w90_prefix))//'.mmn'
883 w90_mmn = io_open(trim(filename), global_namespace, action='write')
884
885 ! write header
886 if (st%system_grp%is_root()) then
887 write(w90_mmn,*) 'Created by oct-wannier90'
888 write(w90_mmn,*) w90_num_bands, w90_num_kpts, w90_nntot
889 end if
890
891 safe_allocate(psin(1:mesh%np, 1:st%d%dim))
892 safe_allocate(phase(1:mesh%np))
893 safe_allocate(overlap(1:w90_num_bands))
894 safe_allocate(ss(1:st%nst))
895
896
897 ! loop over the pairs specified in the nnkp file (read before in init)
898 do ii = 1, w90_num_kpts * w90_nntot
899 ik = w90_nnk_list(1, ii)
900 iknn = w90_nnk_list(2, ii)
901 g(1:3) = w90_nnk_list(3:5, ii)
902 if (st%system_grp%is_root()) write(w90_mmn, '(I10,2x,I10,2x,I3,2x,I3,2x,I3)') ik, iknn, g
903 ! For mixed periodicity we remove the G vectors along the non-periodic directions
904 ! as this correspond to the infinite vacuum limit
905 g(sys%space%periodic_dim+1:sys%space%dim) = 0
906
907 ! For spin-polarized calculations, we select the right k-point
908 if (sys%st%d%ispin == spin_polarized) then
909 ik = (ik-1)*2 + w90_spin_channel
910 iknn = (iknn-1)*2 + w90_spin_channel
911 end if
912
913
914 ! Only treat local k-points
915 if(ik >= st%d%kpt%start .and. ik <= st%d%kpt%end) then
916
917 ! Wannier90 treats everything fully periodic
918 ! Conversion is done with the 3D "correct" klattice
919 call kpoints_to_absolute(sys%ions%latt, real(g, real64) , gcart)
920
921 ! Phase that gives u_{n,k+G}(r) from u_{nk}(r)
922 ! Here the minus sign of Octopus cancels with minus sign of the input G
923 ! (ik and iknn correspond in the list to minus the k-points in Octopus)
924 if (any(g /= 0)) then
925 !$omp parallel do
926 do ip = 1, mesh%np
927 phase(ip) = exp(-m_zi*dot_product(mesh%x(1:3, ip), gcart(1:3)))
928 end do
929 end if
930
931 end if
932
933 ! Loop over distributed bands
934 ! Slow index in M_{mn}^{k,b}, so \psi_n
935 do jst = 1, st%nst
936 if (exclude_list(jst)) cycle
937
938 ! Communication for the local states
939 if ( .not. st%d%kpt%parallel .and. .not. st%parallel_in_states) then
940 call states_elec_get_state(st, mesh, jst, iknn, psin)
941 else
942 node_fr = -1
943 node_to = -1
944 do inode = 0, st%d%kpt%mpi_grp%size-1
945 if(iknn >= st%st_kpt_task(inode,3) .and. iknn <= st%st_kpt_task(inode,4)) then
946 node_fr = inode
947 end if
948 if(ik >= st%st_kpt_task(inode,3) .and. ik <= st%st_kpt_task(inode,4)) then
949 node_to = inode
950 end if
951 end do
952 assert(node_fr > -1)
953 assert(node_to > -1)
954
955 send_req = mpi_request_null
956 ! We have locally the k-point
957 if (state_kpt_is_local(st, jst, iknn)) then
958 call states_elec_get_state(st, mesh, jst, iknn, psin)
959 ! We send it only if we don`t want to use it locally
960 if(node_to /= st%d%kpt%mpi_grp%rank) then
961 call st%d%kpt%mpi_grp%isend(psin, mesh%np*st%d%dim, mpi_double_complex, node_to, send_req)
962 end if
963 end if
964 ! We receive the desired state, only if it is not a local one
965 if(node_to == st%d%kpt%mpi_grp%rank .and. node_to /= node_fr) then
966 call st%d%kpt%mpi_grp%recv(psin, mesh%np*st%d%dim, mpi_double_complex, node_fr)
967 end if
968 if (send_req /= mpi_request_null) then
969 call st%d%kpt%mpi_grp%wait(send_req)
970 end if
971 end if
972
973 overlap = m_zero
974
975 if(ik >= st%d%kpt%start .and. ik <= st%d%kpt%end) then
976
977 ! Do not apply the phase if the phase factor is null
978 if (any(g /= 0)) then
979 ! add phase
980 !$omp parallel
981 do idim = 1, st%d%dim
982 !$omp do
983 do ip = 1, mesh%np
984 psin(ip, idim) = psin(ip, idim) * phase(ip)
985 end do
986 end do
987 !$omp end parallel
988 end if
989
990
991 ! See Eq. (25) in PRB 56, 12847 (1997)
992 ! Fast index in M_{mn}^{k,b}, so m.
993 do ib = st%group%block_start, st%group%block_end
994 batch => st%group%psib(ib, ik)
995 if (all(exclude_list(batch%ist(1:batch%nst)))) cycle
996 call zmesh_batch_mf_dotp(mesh, batch, psin, ss(1:batch%nst), reduce = .false.)
997 do ist = 1, batch%nst
998 if (exclude_list(batch%ist(ist))) cycle
999 overlap(band_index(batch%ist(ist))) = ss(ist)
1000 end do
1001 end do
1002 end if
1003
1004 call profiling_in("W90_MMN_REDUCE")
1005 call mesh%allreduce(overlap)
1006 call profiling_out("W90_MMN_REDUCE")
1007
1008 if(st%d%kpt%parallel) then
1009 call comm_allreduce(st%d%kpt%mpi_grp, overlap)
1010 end if
1011
1012 ! write to W90 file
1013 if (st%system_grp%is_root()) then
1014 do ist = 1, st%nst
1015 if (exclude_list(ist)) cycle
1016 write(w90_mmn,'(e18.10,2x,e18.10)') overlap(band_index(ist))
1017 end do
1018 end if
1019
1020 end do !jst
1021 end do
1022
1023 call io_close(w90_mmn)
1024
1025 safe_deallocate_a(psin)
1026 safe_deallocate_a(phase)
1027 safe_deallocate_a(overlap)
1028 safe_deallocate_a(ss)
1029
1030 call profiling_out("W90_MMN")
1031
1032 pop_sub(create_wannier90_mmn)
1033
1034 end subroutine create_wannier90_mmn
1035
1036 ! --------------------------------------------------------------------------
1037 subroutine create_wannier90_eig()
1038 integer :: ist, ik, w90_eig
1039 character(len=80) :: filename
1040
1041 push_sub(create_wannier90_eig)
1042
1043 if (sys%st%parallel_in_states) then
1044 call messages_not_implemented("w90_eig output with states parallelization")
1045 end if
1046
1047 if (sys%st%system_grp%is_root()) then
1048 filename = './'//trim(adjustl(w90_prefix))//'.eig'
1049 w90_eig = io_open(trim(filename), global_namespace, action='write')
1050 do ik = 1, w90_num_kpts
1051 do ist = 1, sys%st%nst
1052 if (exclude_list(ist)) cycle
1053 if (sys%st%d%ispin /= spin_polarized) then
1054 write(w90_eig,'(I5,2x,I8,2x,e18.10)') band_index(ist), ik, &
1055 units_from_atomic(unit_ev, sys%st%eigenval(ist, ik))
1056 else
1057 write(w90_eig,'(I5,2x,I8,2x,e18.10)') band_index(ist), ik, &
1058 units_from_atomic(unit_ev, sys%st%eigenval(ist, (ik-1)*2+w90_spin_channel))
1059 end if
1060 end do
1061 end do
1062
1063 call io_close(w90_eig)
1064 end if
1065
1066 pop_sub(create_wannier90_eig)
1067 end subroutine create_wannier90_eig
1068
1069 ! --------------------------------------------------------------------------
1070 subroutine write_unk(space, mesh, st, formatted)
1071 class(space_t), intent(in) :: space
1072 class(mesh_t), intent(in) :: mesh
1073 type(states_elec_t), intent(in) :: st
1074 logical, intent(in) :: formatted
1075
1076 integer :: ist, ik, unk_file, ispin
1077 integer :: ix, iy, iz
1078 real(real64) :: w_real, w_imag
1079 character(len=80) :: filename
1080 complex(real64), allocatable :: psi(:)
1081 type(cube_t) :: cube
1082 type(cube_function_t) :: cf
1083
1084 push_sub(write_unk)
1085
1086 if (st%d%kpt%parallel) then
1087 call messages_not_implemented("w90_unk output with k-point parallelization")
1088 end if
1089
1090 if (sys%gr%parallel_in_domains) then
1091 call messages_not_implemented("w90_unk output with domain parallelization")
1092 end if
1093
1094 if (st%parallel_in_states) then
1095 call messages_not_implemented("w90_unk output with states parallelization")
1096 end if
1097
1098 call messages_experimental("Wannier90Files = w90_unk")
1099
1100
1101 safe_allocate(psi(1:mesh%np))
1102
1103 call cube_init(cube, mesh%idx%ll, global_namespace, space, mesh%spacing, &
1104 mesh%coord_system, need_partition=.not.mesh%parallel_in_domains)
1105 call cube_init_cube_map(cube, mesh)
1106
1107 call zcube_function_alloc_rs(cube, cf)
1108
1109 do ik = 1, w90_num_kpts
1110 do ispin = 1, st%d%dim
1111 if (st%system_grp%is_root()) then
1112 write(filename, '(a,i5.5,a1,i1)') './UNK', ik,'.', ispin
1113 ! write header
1114 if (formatted) then
1115 unk_file = io_open(trim(filename), global_namespace, action='write', form='formatted')
1116 write(unk_file, *) mesh%idx%ll(1:mesh%idx%dim), ik, w90_num_bands
1117 else
1118 unk_file = io_open(trim(filename), global_namespace, action='write', form='unformatted')
1119 write(unk_file) mesh%idx%ll(1:mesh%idx%dim), ik, w90_num_bands
1120 end if
1121 end if
1122
1123 ! states
1124 do ist = 1, st%nst
1125 if (exclude_list(ist)) cycle
1126
1127 if (sys%st%d%ispin /= spin_polarized) then
1128 call states_elec_get_state(st, mesh, ispin, ist, ik, psi)
1129 else
1130 call states_elec_get_state(st, mesh, ispin, ist, (ik-1)*2+w90_spin_channel, psi)
1131 end if
1133 ! put the density in the cube
1134 ! Note: At the moment this does not work for domain parallelization
1135 assert(.not. cube%parallel_in_domains)
1136 call zmesh_to_cube(mesh, psi, cube, cf)
1137
1138 if (st%system_grp%is_root()) then
1139 if (formatted) then
1140 do iz=1,cube%rs_n_global(3)
1141 do iy = 1,cube%rs_n_global(2)
1142 do ix = 1,cube%rs_n_global(1)
1143 w_real = real(cf%zrs(ix,iy,iz), real64)
1144 w_imag = aimag(cf%zrs(ix,iy,iz))
1145 write (unk_file, *) w_real, w_imag
1146 end do
1147 end do
1148 end do
1149 else
1150 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))
1151 end if
1152 end if
1153 end do
1154 if (st%system_grp%is_root()) call io_close(unk_file)
1155 end do
1156 end do
1157
1158 call zcube_function_free_rs(cube, cf)
1159 call cube_end(cube)
1160
1161 safe_deallocate_a(psi)
1162
1163 pop_sub(write_unk)
1164
1165 end subroutine write_unk
1166
1167 ! --------------------------------------------------------------------------
1168 subroutine create_wannier90_amn(space, mesh, latt, st, kpoints)
1169 class(space_t), intent(in) :: space
1170 class(mesh_t), intent(in) :: mesh
1171 type(lattice_vectors_t), intent(in) :: latt
1172 type(states_elec_t), intent(in) :: st
1173 type(kpoints_t), intent(in) :: kpoints
1174
1175 integer :: ist, ik, w90_amn, idim, iw, ip, ik_real
1176 real(real64) :: center(3), kpoint(3), threshold
1177 character(len=80) :: filename
1178 complex(real64), allocatable :: psi(:,:), phase(:), projection(:)
1179 real(real64), allocatable :: ylm(:)
1180 type(orbitalset_t), allocatable :: orbitals(:)
1181
1182 push_sub(create_wannier90_amn)
1183 call profiling_in("W90_AMN")
1184
1185 if (st%parallel_in_states) then
1186 call messages_not_implemented("w90_amn output with states parallelization")
1187 end if
1188
1189 filename = './'// trim(adjustl(w90_prefix))//'.amn'
1190 w90_amn = io_open(trim(filename), global_namespace, action='write')
1191
1192 ! write header
1193 if (st%system_grp%is_root()) then
1194 write(w90_amn,*) 'Created by oct-wannier90'
1195 write(w90_amn,*) w90_num_bands, w90_num_kpts, w90_num_wann
1196 end if
1197
1198 if (scdm_proj) then
1199
1200 message(1) = "Info: Writing projections obtained from SCDM."
1201 call messages_info(1)
1202
1203
1204 do ik = 1, w90_num_kpts
1205 do ist = 1, st%nst
1206 if (exclude_list(ist)) cycle
1207 if (st%system_grp%is_root()) then
1208 do iw = 1, w90_nproj
1209 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)
1210 end do
1211 end if
1212 end do !ist
1213 end do! ik
1214
1215 else
1216
1217 message(1) = "Info: Computing the projection matrix"
1218 call messages_info(1)
1219
1220 !We use the variable AOThreshold to deterine the threshold on the radii of the atomic orbitals
1221 call parse_variable(global_namespace, 'AOThreshold', 0.001_real64, threshold)
1222
1223 safe_allocate(orbitals(1:w90_nproj))
1224 ! precompute orbitals
1225 do iw=1, w90_nproj
1226 call orbitalset_init(orbitals(iw))
1227
1228 orbitals(iw)%norbs = 1
1229 orbitals(iw)%ndim = 1
1230 orbitals(iw)%radius = -log(threshold)
1231 orbitals(iw)%use_submesh = .false.
1232
1233 ! cartesian coordinate of orbital center
1234 center(1:3) = latt%red_to_cart(w90_proj_centers(1:3, iw))
1235 call submesh_init(orbitals(iw)%sphere, space, mesh, latt, center, orbitals(iw)%radius)
1236
1237 ! get dorb as submesh points
1238 safe_allocate(ylm(1:orbitals(iw)%sphere%np))
1239 ! (this is a routine from pwscf)
1240 call ylm_wannier(ylm, w90_proj_lmr(iw,1), w90_proj_lmr(iw,2), &
1241 orbitals(iw)%sphere%r, orbitals(iw)%sphere%rel_x, orbitals(iw)%sphere%np)
1242
1243 ! apply radial function
1244 if (w90_proj_lmr(iw,3) == 1) then
1245 do ip = 1,orbitals(iw)%sphere%np
1246 ylm(ip) = ylm(ip)*m_two*exp(-orbitals(iw)%sphere%r(ip))
1247 end do
1248 else
1249 call messages_not_implemented("oct-wannier90: r/=1 for the radial part")
1250 end if
1251
1252 safe_allocate(orbitals(iw)%zorb(1:orbitals(iw)%sphere%np, 1, 1))
1253 orbitals(iw)%zorb(1:orbitals(iw)%sphere%np, 1, 1) = ylm(1:orbitals(iw)%sphere%np)
1254 safe_deallocate_a(ylm)
1255
1256 safe_allocate(orbitals(iw)%phase(1:orbitals(iw)%sphere%np, st%d%kpt%start:st%d%kpt%end))
1257 orbitals(iw)%phase(:,:) = m_z0
1258 safe_allocate(orbitals(iw)%eorb_mesh(1:mesh%np, 1, 1, st%d%kpt%start:st%d%kpt%end))
1259 orbitals(iw)%eorb_mesh(:,:,:,:) = m_z0
1260
1261 call orbitalset_update_phase(orbitals(iw), space%dim, st%d%kpt, kpoints, st%d%ispin == spin_polarized, &
1262 kpt_max = w90_num_kpts)
1264 end do
1265
1266 safe_allocate(psi(1:mesh%np, 1:st%d%dim))
1267 safe_allocate(phase(1:mesh%np))
1268 safe_allocate(projection(1:w90_nproj))
1269
1270 do ik = 1, w90_num_kpts
1271 kpoint(1:space%dim) = kpoints%get_point(ik)
1272 !$omp parallel do
1273 do ip = 1, mesh%np
1274 phase(ip) = exp(-m_zi* sum(mesh%x(1:space%dim, ip) * kpoint(1:space%dim)))
1275 end do
1276
1277 !For spin-polarized calculations, we select the right k-point
1278 if (st%d%ispin == spin_polarized) then
1279 ik_real = (ik-1)*2 + w90_spin_channel
1280 else
1281 ik_real = ik
1282 end if
1283
1284
1285 do ist = 1, st%nst
1286 if (exclude_list(ist)) cycle
1287
1288 projection = m_zero
1289
1290 if(ik_real >= st%d%kpt%start .and. ik_real <= st%d%kpt%end) then
1291 call states_elec_get_state(st, mesh, ist, ik_real, psi)
1292
1293 !$omp parallel
1294 do idim = 1, st%d%dim
1295 !The minus sign is here is for the wrong convention of Octopus
1296 !$omp do
1297 do ip = 1, mesh%np
1298 psi(ip, idim) = psi(ip, idim)*phase(ip)
1299 end do
1300 end do
1301 !$omp end parallel
1302
1303 do iw = 1, w90_nproj
1304 idim = 1
1305 if (w90_spinors) idim = w90_spin_proj_component(iw)
1306
1307 !At the moment the orbitals do not depend on idim
1308 !The idim index for eorb_mesh would be for a spin-resolved orbital like j=1/2
1309 projection(iw) = zmf_dotp(mesh, psi(1:mesh%np,idim), &
1310 orbitals(iw)%eorb_mesh(1:mesh%np,1,1,ik_real), reduce = .false.)
1311 end do
1312
1313 call profiling_in("W90_AMN_REDUCE")
1314 call mesh%allreduce(projection)
1315 call profiling_out("W90_AMN_REDUCE")
1316 end if
1317
1318 if(st%d%kpt%parallel) then
1319 call comm_allreduce(st%d%kpt%mpi_grp, projection)
1320 end if
1321
1322 if (st%system_grp%is_root()) then
1323 do iw = 1, w90_nproj
1324 write (w90_amn,'(I5,2x,I5,2x,I5,2x,e18.10,2x,e18.10)') band_index(ist), iw, ik, projection(iw)
1325 end do
1326 end if
1327 end do !ist
1328 end do !ik
1329
1330 safe_deallocate_a(psi)
1331 safe_deallocate_a(phase)
1332 safe_deallocate_a(projection)
1333
1334 do iw = 1, w90_nproj
1335 call orbitalset_end(orbitals(iw))
1336 end do
1337 safe_deallocate_a(orbitals)
1338 end if
1339
1340 call io_close(w90_amn)
1341
1342 call profiling_out("W90_AMN")
1343
1344 pop_sub(create_wannier90_amn)
1345
1346 end subroutine create_wannier90_amn
1347
1348 ! --------------------------------------------------------------------------
1352 subroutine create_wannier90_spn(mesh, st)
1353 class(mesh_t), intent(in) :: mesh
1354 type(states_elec_t), target, intent(in) :: st
1355
1356 integer :: ist, jst, ik, w90_spn, counter
1357 character(len=80) :: filename
1358 complex(real64), allocatable :: spin(:,:,:)
1359 complex(real64), allocatable :: psim(:,:), psin(:,:)
1360 complex(real64) :: dot_upup, dot_updown, dot_downup, dot_downdown
1361
1362 push_sub(create_wannier90_spn)
1363 call profiling_in("W90_SPN")
1364
1365 assert(st%d%ispin == spinors)
1366
1367 if (st%parallel_in_states) then
1368 call messages_not_implemented("w90_spn output with states parallelization")
1369 end if
1370
1371 message(1) = "Info: Computing the spin file"
1372 call messages_info(1)
1373
1374 filename = './'// trim(adjustl(w90_prefix))//'.spn'
1375 w90_spn = io_open(trim(filename), global_namespace, action='write')
1376
1377 ! write header
1378 if (st%system_grp%is_root()) then
1379 write(w90_spn,*) 'Created by oct-wannier90'
1380 write(w90_spn,*) w90_num_bands, w90_num_kpts
1381 end if
1382
1383 safe_allocate(psim(1:mesh%np, 1:st%d%dim))
1384 safe_allocate(psin(1:mesh%np, 1:st%d%dim))
1385 safe_allocate(spin(1:3, 1:(w90_num_bands*(w90_num_bands+1))/2, 1:w90_num_kpts))
1386 spin = m_zero
1387
1388 ! loop over the pairs specified in the nnkp file (read before in init)
1389 do ik = st%d%kpt%start, st%d%kpt%end
1390 counter = 0
1391 do jst = 1, st%nst
1392 if (exclude_list(jst)) cycle
1393
1394 call states_elec_get_state(st, mesh, jst, ik, psim)
1395 do ist = 1, jst
1396 if (exclude_list(ist)) cycle
1397
1398 counter = counter + 1
1399
1400 call states_elec_get_state(st, mesh, ist, ik, psin)
1401
1402 dot_upup = zmf_dotp(mesh, psin(:, 1), psim(:, 1), reduce = .false.)
1403 dot_downdown = zmf_dotp(mesh, psin(:, 2), psim(:, 2), reduce = .false.)
1404 dot_updown = zmf_dotp(mesh, psin(:, 1), psim(:, 2), reduce = .false.)
1405 dot_downup = zmf_dotp(mesh, psin(:, 2), psim(:, 1), reduce = .false.)
1406
1407 spin(1, counter, ik) = dot_updown + dot_downup
1408 spin(2, counter, ik) = -m_zi * dot_updown + m_zi * dot_downup
1409 spin(3, counter, ik) = dot_upup - dot_downdown
1410 end do !ist
1411 end do
1412 end do
1413
1414 call profiling_in("W90_SPN_REDUCE")
1415 call mesh%allreduce(spin)
1416
1417 if(st%d%kpt%parallel) then
1418 call comm_allreduce(st%d%kpt%mpi_grp, spin)
1419 end if
1420 call profiling_out("W90_SPN_REDUCE")
1421
1422 ! write to W90 file
1423 if (st%system_grp%is_root()) then
1424 do ik = 1, w90_num_kpts
1425 counter = 0
1426 do jst = 1, st%nst
1427 if (exclude_list(jst)) cycle
1428
1429 do ist = 1, jst
1430 if (exclude_list(ist)) cycle
1431
1432 counter = counter + 1
1433 write(w90_spn, '(e18.10,2x,e18.10)') spin(1, counter, ik)
1434 write(w90_spn, '(e18.10,2x,e18.10)') spin(2, counter, ik)
1435 write(w90_spn, '(e18.10,2x,e18.10)') spin(3, counter, ik)
1436 end do
1437 end do
1438 end do !ik
1439 end if
1440
1441 call io_close(w90_spn)
1442
1443 safe_deallocate_a(psim)
1444 safe_deallocate_a(psin)
1445 safe_deallocate_a(spin)
1446
1447 call profiling_out("W90_SPN")
1448
1449 pop_sub(create_wannier90_spn)
1450 end subroutine create_wannier90_spn
1451
1452
1453 ! --------------------------------------------------------------------------
1454 subroutine generate_wannier_states(space, mesh, ions, st, kpoints)
1455 class(space_t), intent(in) :: space
1456 class(mesh_t), intent(in) :: mesh
1457 type(ions_t), intent(in) :: ions
1458 type(states_elec_t), intent(in) :: st
1459 type(kpoints_t), intent(in) :: kpoints
1460
1461 integer :: w90_u_mat, w90_xyz, nwann, nik
1462 integer :: ik, iw, iw2, ip, ipmax, rankmax, idmmax
1463 real(real64), allocatable :: centers(:,:), supercell_centers(:,:), new_centers(:,:)
1464 complex(real64), allocatable :: Umnk(:,:,:)
1465 complex(real64), allocatable :: zwn(:,:,:), psi(:,:), phase(:,:), phase_bloch(:), zwn_bloch(:,:,:)
1466 character(len=MAX_PATH_LEN) :: fname
1467 real(real64) :: kpoint(3), wmod, wmodmax, xx(space%dim)
1468 character(len=2) :: dum
1469 logical :: exist
1470 type(unit_t) :: fn_unit
1471 complex(real64) :: scal
1472 type(block_t) :: blk
1473 integer :: supercell(space%dim), ii, jj, kk, ncols, Nreplica, irep, irepmax
1474 real(real64) :: min_image_displ(3), offset(space%dim)
1475 integer :: jw
1476 integer, allocatable :: parent(:)
1477 real(real64), parameter :: tol_cluster = 0.25_real64 ! In Bohr
1478
1479
1480 push_sub(generate_wannier_states)
1481
1482 message(1) = "oct-wannier90: Constructing the Wannier states from the U matrix."
1483 call messages_info(1)
1484
1485 inquire(file=trim(trim(adjustl(w90_prefix))//'_centres.xyz'),exist=exist)
1486 if (.not. exist) then
1487 message(1) = 'oct-wannier90: Cannot find the Wannier90 file seedname_centres.xyz.'
1488 write(message(2),'(a)') 'Please run wannier90.x with "write_xyz=.true." in '// trim(adjustl(w90_prefix)) // '.'
1489 call messages_fatal(2)
1490 end if
1491
1492 w90_xyz = io_open(trim(trim(adjustl(w90_prefix))//'_centres.xyz'), global_namespace, action='read')
1493
1494 safe_allocate(centers(1:3, 1:w90_num_wann))
1495 !Skip two lines
1496 read(w90_xyz, *)
1497 read(w90_xyz, *)
1498 do iw = 1, w90_num_wann
1499 read(w90_xyz, *) dum, centers(1:3, iw)
1500 ! Wannier90 outputs the coordinates in angstrom
1501 centers(1:3, iw) = units_to_atomic(unit_angstrom, centers(1:3, iw))
1502 end do
1503 call io_close(w90_xyz)
1504
1505 ! In order to find "more consistent" Wannier centers, the centers are clustered in groups,
1506 ! Using periodic boundary condition to find the centers that are the closest
1507 safe_allocate(parent(1:w90_num_wann))
1508 do iw = 1, w90_num_wann
1509 parent(iw) = iw
1510 do jw = 1, iw-1
1511 min_image_displ(:) = ions%latt%cart_to_red(centers(:, iw) - centers(:, jw))
1512 min_image_displ(1:space%periodic_dim) = min_image_displ(1:space%periodic_dim) - nint(min_image_displ(1:space%periodic_dim))
1513 min_image_displ = ions%latt%red_to_cart(min_image_displ)
1514 if (norm2(min_image_displ) < tol_cluster) then
1515 parent(iw) = parent(jw)
1516 exit
1517 end if
1518 end do
1519 end do
1520
1521 message(1) = "Info : Clustering of the Wannier centers"
1522 call messages_info(1)
1523
1524 safe_allocate(new_centers(1:3, 1:w90_num_wann))
1525 do iw = 1, w90_num_wann
1526 write(message(1), '(a,i0,a,3(f7.3,a))') 'Info : Original Wannier center ', &
1527 iw, ' (', centers(1, iw), ', ', centers(2, iw), ', ', centers(3, iw), ')'
1528
1529 if (parent(iw) == iw) then
1530 ! We are computing |w_{n,0}>, so we need to take only a shift to get to the central cell
1531 new_centers(1:3, iw) = ions%latt%fold_into_cell(centers(1:3, iw))
1532 else
1533 ! This center has a closeby periodic parent. We then move it to be as close as possible to its "parent"
1534 ! Thanks to the loop above, this should always be inside of very close to a parent inside the unit cell
1535 min_image_displ(:) = ions%latt%cart_to_red(centers(:, iw) - new_centers(:, parent(iw)))
1536 min_image_displ(1:space%periodic_dim) = real(nint(min_image_displ(1:space%periodic_dim)), real64)
1537 min_image_displ = ions%latt%red_to_cart(min_image_displ)
1538 new_centers(1:3, iw) = centers(1:3, iw) - min_image_displ
1539 end if
1540
1541 write(message(2), '(a,i0,a,3(f7.3,a))') 'Info : New Wannier center ', &
1542 iw, ' (', new_centers(1, iw), ', ', new_centers(2, iw), ', ', new_centers(3, iw), ')'
1543 write(message(3), '(a)') ''
1544 call messages_info(3)
1545 end do
1546
1547 ! Getting the offset, for the correct phase factor
1548 centers = new_centers - centers
1549 safe_deallocate_a(parent)
1550 safe_deallocate_a(new_centers)
1551
1552 inquire(file=trim(trim(adjustl(w90_prefix))//'_u_dis.mat'),exist=exist)
1553 if (exist) then
1554 message(1) = 'oct-wannier90: Calculation of Wannier states with disentanglement is not yet supported.'
1555 call messages_fatal(1)
1556 end if
1557
1558 inquire(file=trim(trim(adjustl(w90_prefix))//'_u.mat'),exist=exist)
1559 if (.not. exist) then
1560 message(1) = 'oct-wannier90: Cannot find the Wannier90 seedname_u.mat file.'
1561 write(message(2),'(a)') 'Please run wannier90.x with "write_u_matrices=.true." in '// trim(adjustl(w90_prefix)) // '.'
1562 call messages_fatal(2)
1563 end if
1564 w90_u_mat = io_open(trim(trim(adjustl(w90_prefix))//'_u.mat'), global_namespace, action='read')
1565
1566
1567 !Skip one line
1568 read(w90_u_mat, *)
1569 !Read num_kpts, num_wann, num_wann for consistency check
1570 read(w90_u_mat, *) nik, nwann, nwann
1571 if (nik /= w90_num_kpts .or. nwann /= w90_num_wann) then
1572 message(1) = "The file contains U matrices is inconsistent with the .win file."
1573 call messages_fatal(1)
1574 end if
1575
1576 safe_allocate(umnk(1:w90_num_wann, 1:w90_num_wann, 1:w90_num_kpts))
1577
1578 do ik = 1, w90_num_kpts
1579 !Skip one line
1580 read(w90_u_mat, *)
1581 !Skip one line (k-point coordinate)
1582 read(w90_u_mat, *)
1583 read(w90_u_mat, '(f15.10,sp,f15.10)') ((umnk(iw, iw2, ik), iw=1, w90_num_wann), iw2=1, w90_num_wann)
1584 end do
1585
1586 call io_close(w90_u_mat)
1587
1588 !We read the output format for the Wannier states
1589 call parse_variable(global_namespace, 'OutputFormat', 0, how)
1590 if (how == 0) then
1591 message(1) = "OutputFormat must be specified for outputing Wannier functions."
1592 call messages_fatal(1)
1593 end if
1594
1595 !%Variable Wannier90Supercell
1596 !%Type block
1597 !%Section Utilities::oct-wannier90
1598 !%Description
1599 !% This block allows to specify the size of the supercell used to compute the Wannier functions
1600 !% If not specified, the code uses a default 1x1x1 cell, i.e., it plots the Wannier90 in the primitive cell.
1601 !%End
1602 if (parse_is_defined(sys%namespace, 'Wannier90Supercell')) then
1603 if (parse_block(sys%namespace, 'Wannier90Supercell', blk) == 0) then
1604 ncols = parse_block_cols(blk, 0)
1605 if (ncols /= space%dim) then
1606 write(message(1),'(a,i3,a,i3)') 'Wannier90Supercell has ', ncols, ' columns but must have ', sys%space%dim
1607 call messages_fatal(1, namespace=sys%namespace)
1608 end if
1609 do ii = 1, space%dim
1610 call parse_block_integer(blk, 0, ii - 1, supercell(ii))
1611 end do
1612
1613 call parse_block_end(blk)
1614 end if
1615 else
1616 supercell = 1
1617 end if
1618
1619 nreplica = product(supercell)
1620
1621 ! The center of each replica of the unit cell
1622 safe_allocate(supercell_centers(1:space%dim, 1:nreplica))
1623 offset(1:space%dim) = -floor((real(supercell(1:space%dim), real64) - m_one) / m_two)
1624 irep = 1
1625 do ii = 0, supercell(1)-1
1626 do jj = 0, supercell(2)-1
1627 do kk = 0, supercell(3)-1
1628 supercell_centers(:, irep) = ions%latt%red_to_cart(offset &
1629 + [real(ii, real64), real(jj, real64), real(kk, real64)])
1630 irep = irep + 1
1631 end do
1632 end do
1633 end do
1634
1635
1636
1637 call io_mkdir('wannier', global_namespace)
1638
1639 !Computing the Wannier states in the primitive cell, from the U matrices
1640 safe_allocate(zwn(1:mesh%np, 1:nreplica, 1:st%d%dim))
1641 safe_allocate(psi(1:mesh%np, 1:st%d%dim))
1642 safe_allocate(phase(1:mesh%np, 1:nreplica))
1643 safe_allocate(phase_bloch(1:mesh%np))
1644 if (w90_bloch_sums) then
1645 safe_allocate(zwn_bloch(1:mesh%np, 1:st%d%dim, st%d%kpt%start:st%d%kpt%end))
1646 end if
1647
1648 do iw = 1, w90_num_wann
1649
1650 zwn(:, :, :) = m_z0
1651
1652 do ik = 1, w90_num_kpts
1653
1654 if (.not. (ik >= st%d%kpt%start .and. ik <= st%d%kpt%end)) cycle
1655
1656 if (w90_bloch_sums) zwn_bloch(:,:,ik) = m_z0
1657
1658 kpoint(1:space%dim) = kpoints%get_point(ik, absolute_coordinates=.true.)
1659
1660 ! We compute the Wannier orbital on a grid centered around the Wannier function
1661 ! The minus sign is here is for the wrong convention of Octopus
1662 do irep = 1, nreplica
1663 !$omp parallel do
1664 do ip = 1, mesh%np
1665 xx = mesh%x(1:space%dim, ip)-centers(1:space%dim, iw) + supercell_centers(1:space%dim, irep)
1666 phase(ip, irep) = exp(-m_zi* sum( xx * kpoint(1:space%dim)))
1667 end do
1668 end do
1669 if (w90_bloch_sums) then
1670 do ip = 1, mesh%np
1671 xx = mesh%x(1:space%dim, ip)
1672 phase_bloch(ip) = exp(-m_zi* sum( xx * kpoint(1:space%dim)))
1673 end do
1674 end if
1675
1676 do iw2 = 1, st%nst
1677 if (exclude_list(iw2)) cycle
1678
1679 if (st%d%ispin /= spin_polarized) then
1680 call states_elec_get_state(st, mesh, iw2, ik, psi)
1681 else
1682 call states_elec_get_state(st, mesh, iw2, (ik-1)*2+w90_spin_channel, psi)
1683 end if
1684
1685 !$omp parallel
1686 do idim = 1, st%d%dim
1687 do irep = 1, nreplica
1688 !$omp do
1689 do ip = 1, mesh%np
1690 zwn(ip, irep, idim) = zwn(ip, irep, idim) + umnk(band_index(iw2), iw, ik) * psi(ip, idim) * phase(ip, irep)
1691 end do
1692 end do
1693 end do
1694 !$omp end parallel
1695
1696 ! See Eq. 19 in arXiv:0605539
1697 if (w90_bloch_sums) then
1698 !$omp parallel
1699 do idim = 1, st%d%dim
1700 !$omp do
1701 do ip = 1, mesh%np
1702 zwn_bloch(ip, idim, ik) = zwn_bloch(ip, idim, ik) &
1703 + umnk(band_index(iw2), iw, ik) * psi(ip, idim) * phase_bloch(ip)
1704 end do
1705 end do
1706 !$omp end parallel
1707 end if
1708 end do!iw2
1709 end do!ik
1710
1711 if(st%d%kpt%parallel) then
1712 call comm_allreduce(st%d%kpt%mpi_grp, zwn)
1713 end if
1714
1715 ! Following what Wannier90 is doing, we fix the global phase by setting the max to be real
1716 ! We also normalize to the number of k-point at this step
1717 if (sys%st%d%ispin /= spinors) then
1718 ipmax = 0
1719 irepmax = 0
1720 wmodmax = m_zero
1721 do irep = 1, nreplica
1722 do ip = 1, mesh%np
1723 wmod = real(zwn(ip, irep, 1)*conjg(zwn(ip, irep, 1)), real64)
1724 if (wmod > wmodmax) then
1725 ipmax = ip
1726 irepmax = irep
1727 wmodmax = wmod
1728 end if
1729 end do
1730 end do
1731 scal = sqrt(wmodmax)/zwn(ipmax, irepmax, 1)/w90_num_kpts
1732 call mesh_minmaxloc(mesh, wmodmax, rankmax, mpi_maxloc)
1733 call mesh%mpi_grp%bcast(scal, 1, mpi_double_complex, rankmax)
1734 call lalg_scal(mesh%np, nreplica, scal, zwn(:,:,1))
1735
1736 if (w90_bloch_sums) then
1737 do ik = st%d%kpt%start, st%d%kpt%end
1738 ipmax = 0
1739 idmmax= 0
1740 wmodmax = m_zero
1741 do idim = 1, st%d%dim
1742 do ip = 1, mesh%np
1743 wmod = real(zwn_bloch(ip, idim, ik)*conjg(zwn_bloch(ip, idim, ik)), real64)
1744 if (wmod > wmodmax) then
1745 ipmax = ip
1746 wmodmax = wmod
1747 idmmax = idim
1748 end if
1749 end do
1750 end do
1751 scal = sqrt(wmodmax)/zwn_bloch(ipmax, idmmax, ik)/w90_num_kpts
1752 call mesh_minmaxloc(mesh, wmodmax, rankmax, mpi_maxloc)
1753 call mesh%mpi_grp%bcast(scal, 1, mpi_double_complex, rankmax)
1754 call lalg_scal(mesh%np, st%d%dim, scal, zwn_bloch(:,:,ik))
1755 end do
1756 end if
1757 end if
1758
1759 ! Output the Wannier states
1760 fn_unit = sqrt(units_out%length**(-space%dim))
1761 do idim = 1, st%d%dim
1762 if (st%d%ispin == spinors) then
1763 write(fname, '(a,i3.3,a4,i1)') 'wannier-', iw, '-isp', idim
1764 else
1765 write(fname, '(a,i3.3,a4,i1)') 'wannier-', iw
1766 end if
1767 if (any(supercell_centers > 1)) then
1768 call io_function_output_supercell(how, "wannier", trim(fname), mesh, &
1769 space, ions%latt, zwn(:, :, idim), supercell_centers, supercell, fn_unit, ierr, global_namespace, &
1770 pos=ions%pos, atoms=ions%atom, grp = st%dom_st_kpt_mpi_grp)
1771
1772 else
1773 call zio_function_output(how, "wannier", trim(fname), global_namespace, space, mesh, &
1774 zwn(:, 1, idim), fn_unit, ierr, pos=ions%pos, atoms=ions%atom, grp = st%dom_st_kpt_mpi_grp)
1775 end if
1776 end do
1777
1778 ! Output Bloch sums of Wannier states
1779 if (w90_bloch_sums) then
1780 do ik = st%d%kpt%start, st%d%kpt%end
1781 do idim = 1, st%d%dim
1782 if (st%d%ispin == spinors) then
1783 write(fname, '(a,i3.3,a4,i1,a3,i5.5)') 'wannier_bloch-', iw, '-isp', idim, '-ik', ik
1784 else
1785 write(fname, '(a,i3.3,a4,i1,a3,i5.5)') 'wannier_bloch-', iw, '-ik', ik
1786 end if
1787 call zio_function_output(how, "wannier", trim(fname), global_namespace, space, mesh, &
1788 zwn_bloch(:, idim, ik), fn_unit, ierr, pos=ions%pos, atoms=ions%atom)
1789 end do
1790 end do
1791 end if
1792
1793 ! Checking the ratio imag/real
1794 if (sys%st%d%ispin /= spinors) then
1795 wmodmax = m_zero
1796 do irep = 1, nreplica
1797 do ip = 1, mesh%np
1798 if(abs(real(zwn(ip, irep, 1), real64)) >= 1e-2_real64) then
1799 wmodmax = max(wmodmax, abs(aimag(zwn(ip, irep, 1)))/abs(real(zwn(ip, irep, 1), real64)))
1800 end if
1801 end do
1802 end do
1803 call mesh_minmaxloc(mesh, wmodmax, rankmax, mpi_maxloc)
1804
1805 write(message(1), '(a,i4,a,f11.6)') 'oct-wannier90: Wannier function ', iw, ' Max. Im/Re Ratio = ', wmodmax
1806 call messages_info(1)
1807 else
1808 write(message(1), '(a,i4)') 'oct-wannier90: Wannier function done ', iw
1809 call messages_info(1)
1810 end if
1811 end do
1812
1813 safe_deallocate_a(umnk)
1814 safe_deallocate_a(zwn)
1815 safe_deallocate_a(psi)
1816 safe_deallocate_a(phase)
1817 safe_deallocate_a(phase_bloch)
1818 safe_deallocate_a(centers)
1819 safe_deallocate_a(supercell_centers)
1820
1822 end subroutine generate_wannier_states
1823
1824end program wannier90_interface
1825
1826!! Local Variables:
1827!! mode: f90
1828!! coding: utf-8
1829!! End:
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double floor(double __x) __attribute__((__nothrow__
This module implements batches of mesh functions.
Definition: batch.F90:135
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 zcube_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:202
subroutine, public global_end()
Finalise parser varinfo file, and MPI.
Definition: global.F90:494
real(real64), parameter, public m_huge
Definition: global.F90:218
real(real64), parameter, public m_zero
Definition: global.F90:200
complex(real64), parameter, public m_z0
Definition: global.F90:210
complex(real64), parameter, public m_zi
Definition: global.F90:214
subroutine, public global_init(communicator)
Initialise Octopus.
Definition: global.F90:375
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_one
Definition: global.F90:201
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:1137
System information (time, memory, sysname)
Definition: loct.F90:117
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:118
subroutine, public zmesh_batch_mf_dotp(mesh, aa, psi, dot, reduce, nst)
calculate the dot products between a batch and a vector of mesh functions
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:1068
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:1040
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:135
subroutine, public orbitalset_init(this)
Definition: orbitalset.F90:210
subroutine, public orbitalset_end(this)
Definition: orbitalset.F90:236
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:286
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:184
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:227
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:221
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 write_unk(space, mesh, st, formatted)
subroutine create_wannier90_mmn(mesh, st)
subroutine wannier90_setup(ions, kpoints, space)
subroutine generate_wannier_states(space, mesh, ions, st, kpoints)
program wannier90_interface
subroutine create_wannier90_amn(space, mesh, latt, st, kpoints)
subroutine wannier90_output()