Octopus
wannier.F90
Go to the documentation of this file.
1!! Copyright (C) A Buccheri, J Reimann. 2026
2!!
3!! This Source Code Form is subject to the terms of the Mozilla Public
4!! License, v. 2.0. If a copy of the MPL was not distributed with this
5!! file, You can obtain one at https://mozilla.org/MPL/2.0/.
6!!
7
8#include "global.h"
9
12program wannier
13 use, intrinsic :: iso_fortran_env
14
16 use debug_oct_m
19 use fft_oct_m
20 use global_oct_m
21 use grid_oct_m
22 use io_oct_m
24 use ions_oct_m
26 use mpi_oct_m
30 use parser_oct_m
35 use unit_oct_m
40
41 ! External Wannier 90 library
42 use w90_library
43 use w90_library_extra, only:overlaps
44
45 implicit none
46
47 type(namespace_t) :: namespace
48 type(electrons_t), pointer :: sys
49 type(wannier_opts_t) :: wannier_opts
50 integer, allocatable :: band_index(:)
51
52 type(lib_common_type) :: w90main
53
54 complex(real64), allocatable :: m_matrix(:, :, :, :)
55 complex(real64), allocatable :: u_matrix(:, :, :)
56 complex(real64), allocatable :: u_matrix_opt(:, :, :)
57 real(real64), allocatable :: eigenvals(:,:)
58
59 integer, allocatable :: nnkp(:,:), gkpb(:,:,:)
60 logical, allocatable :: exclude_list(:)
61 integer :: nn
62
63 integer :: idir, ii, itemp, ik, ist
64
65 integer :: ierr
66 real(real64) :: factor(3)
67
68 ! Initialise all Octopus singletons
69 call global_init()
70 call parser_init()
71 call messages_init()
72 call io_init()
73 namespace = namespace_t("Wannier90Lib", parent = global_namespace)
74 call profiling_init(namespace)
75 call fft_all_init(namespace)
76 call unit_system_init(namespace)
77
78 ! Initialise a system object
79 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
80 sys => electrons_t(global_namespace, mpi_world, int(option__calculationmode__dummy, int32))
81
82 if (sys%space%dim /= 3) then ! see issue #1466
83 call messages_not_implemented("oct-wannier90lib: only 3D is supported")
84 end if
85
86 ! Sanity checks
87 if (sys%kpoints%use_symmetries) then
88 message(1) = 'oct-wannier90: k-points symmetries are not allowed'
89 call messages_fatal(1)
90 end if
91 if (sys%kpoints%use_time_reversal) then
92 message(1) = 'oct-wannier90: time-reversal symmetry is not allowed'
93 call messages_fatal(1)
94 end if
95 if (sys%kpoints%reduced%nshifts > 1) then
96 message(1) = 'oct-wannier90: Wannier90 does not allow for multiple shifts of the k-point grid'
97 call messages_fatal(1)
98 end if
99 if (sys%st%d%nspin == 4) then
100 call messages_not_implemented('oct-wannier90: Spinors currently not supported', namespace)
101 end if
102
103 ! "Correct" rlattice/klattice for Wannier90 (3D periodicity assumed here).
104 ! Note: this is how the lattice is scaled in src/utils/wannier90_interface.F90
105 factor = m_one
106 do idir = sys%space%periodic_dim+1, sys%space%dim
107 factor(idir) = m_two * sys%gr%box%bounding_box_l(idir)
108 end do
109 call sys%ions%latt%scale(factor)
110
111 ! Parsing all input related to wannier90
112 call wannier_opts%parse_oct(namespace)
113 call wannier_opts%parse_win()
114
115 ! Initialize wannier90 lib object
116 call wannier90lib_init_w90main(namespace, sys%ions, sys%kpoints, sys%st, &
117 wannier_opts, w90main, stdout, stderr, ierr)
118 if (ierr /= 0) then
119 write(message(1),'(a,i0)') 'Error initializing wannier90 library: ', ierr
120 call messages_fatal(1)
121 end if
122
123 ! Check for consistency of spin polarization
124 if (sys%st%d%ispin /= unpolarized) then
125 call messages_experimental("oct-wannier90 with SpinComponents /= unpolarized")
126 elseif(sys%st%d%ispin == unpolarized .and. w90main%wvfn_read%spin_channel == 2) then
127 w90main%wvfn_read%spin_channel = 1
128 message(1) = "octopus was run with SpinComponents == unpolarized. Ignoring wannier90 spin input variable"
129 call messages_warning(1)
130 end if
131
132 ! Load octopus states
133 call wannier_calc_load_restart(global_namespace, sys%mc, sys%space, sys%st, sys%gr, sys%kpoints, wannier_opts%restart_from)
134
135 ! Convert the exclude bands to exclude list
136 safe_allocate(band_index(1:sys%st%nst))
137 safe_allocate(exclude_list(1:sys%st%nst))
138 exclude_list(1:sys%st%nst) = .false.
139
140 if (allocated(w90main%exclude_bands)) then
141 do itemp = 1, size(w90main%exclude_bands)
142 exclude_list(w90main%exclude_bands(itemp)) = .true.
143 end do
144 end if
145
146 itemp = 0
147 do ii = 1, sys%st%nst
148 if (exclude_list(ii)) cycle
149 itemp = itemp + 1
150 band_index(ii) = itemp
151 end do
152
153 ! Initial setup (previously in nnkp file)
154 call w90_get_nn(w90main, nn, stdout, stderr, ierr)
155 safe_allocate(nnkp(1:w90main%num_kpts, 1:nn))
156 safe_allocate(gkpb(1:3, 1:w90main%num_kpts, 1:nn))
157 call w90_get_nnkp(w90main, nnkp, stdout, stderr, ierr)
158 call w90_get_gkpb(w90main, gkpb, stdout, stderr, ierr)
159
160 ! Prepare computation of quantities required by Wannier90
161 safe_allocate(m_matrix(1:wannier_opts%num_bands, 1:wannier_opts%num_bands, 1:nn, 1:w90main%num_kpts))
162 safe_allocate(u_matrix_opt(1:wannier_opts%num_bands, 1:wannier_opts%num_wann, 1:w90main%num_kpts))
163 safe_allocate(eigenvals(1:wannier_opts%num_bands, 1:w90main%num_kpts))
164 safe_allocate(u_matrix(1:wannier_opts%num_wann, 1:wannier_opts%num_wann, 1:w90main%num_kpts))
165 call w90_set_m_local(w90main, m_matrix)
166 call w90_set_u_opt(w90main, u_matrix_opt)
167 call w90_set_u_matrix(w90main, u_matrix)
168
169 ! Get eigenvalues from octopus, shape is (num_bands, nk)
170 do ik = 1, w90main%num_kpts
171 do ist = 1, sys%st%nst
172 if (exclude_list(ist)) cycle
173 if (sys%st%d%ispin /= spin_polarized) then
174 eigenvals(band_index(ist), ik) = units_from_atomic(unit_ev, sys%st%eigenval(ist, ik))
175 else
176 eigenvals(band_index(ist), ik) = units_from_atomic(unit_ev, sys%st%eigenval(ist, (ik-1)*2+w90main%wvfn_read%spin_channel))
177 end if
178 end do
179 end do
180 call w90_set_eigval(w90main, eigenvals)
181
182 ! Compute or read quantities required by wannier90
183 if (wannier_opts%calc_overlaps) then
184 call wannier90lib_create_wannier90_mmn(w90main, exclude_list, band_index, sys%gr, sys%st, sys%ions, m_matrix)
185 call wannier90lib_create_wannier90_amn(w90main, wannier_opts, exclude_list, band_index, sys%space, &
186 sys%gr, sys%ions%latt, sys%st, sys%kpoints, u_matrix_opt)
187 ! TODO: Revisit spin-polarised functionality once spin-unpolarised works
188 ! call create_wannier90_spn(sys%gr, sys%st)
189 ! TODO: Add write functions here and remove dump_inputs variable in wannier90
190 else
191 call overlaps(w90main, stdout, stderr, ierr)
192 if (ierr /= 0) then
193 write(message(1), '(a,i0)') 'Error while reading overlaps with wannier90: ', ierr
194 call messages_fatal(1)
195 end if
196 end if
197
198 ! Perform wannierization
199 if (wannier_opts%wannierize) then
200 call w90_disentangle(w90main, stdout, stderr, ierr)
201 if (ierr /= 0) then
202 write(message(1), '(a,i0)') 'Error in w90_disentangle: ', ierr
203 call messages_fatal(1)
204 end if
205 call w90_project_overlap(w90main, stdout, stderr, ierr)
206
208 if (ierr /= 0) then
209 write(message(1), '(a,i0)') 'Error in w90_project_overlap: ', ierr
210 call messages_fatal(1)
211 end if
212 call w90_wannierise(w90main, stdout, stderr, ierr)
213 if (ierr /= 0) then
214 write(message(1), '(a,i0)') 'Error in w90_wannierise: ', ierr
215 call messages_fatal(1)
216 end if
217 ! Avoid plotting from Wannier90
218 w90main%w90_calculation%wannier_plot = .false.
219 ! Output U matrices, hr.dat and more output files for plotting with octopus
220 call w90_plot(w90main, stdout, stderr, ierr)
221 if (ierr /= 0) then
222 write(message(1), '(a,i0)') 'Error in w90_plot: ', ierr
223 call messages_fatal(1)
224 end if
225 end if
226 ! if (wan_opts%plot) then
227 ! Here we generate wannier functions
228 ! Currently this is only meaningful after performing the wannierization
229 ! TODO: Check functionality to read U matrix from file
230 ! generate_wannier_states(space, mesh, ions, st, kpoints)
231 ! TODO: Port function to generate wannier states from old utility
232 ! end if
233
234 ! Free memory of variables in this scope
235 safe_deallocate_a(m_matrix)
236 safe_deallocate_a(u_matrix)
237 safe_deallocate_a(u_matrix_opt)
238 safe_deallocate_a(eigenvals)
239 safe_deallocate_a(exclude_list)
240 safe_deallocate_a(band_index)
241 safe_deallocate_a(nnkp)
242 safe_deallocate_a(gkpb)
243 safe_deallocate_p(sys)
244
245 ! End all singletons
246 call fft_all_end()
247 call io_end()
248 call profiling_end(namespace)
249 call messages_end()
250 call parser_end()
251 call global_end()
252
253end program wannier
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
integer, parameter, public unpolarized
Parameters...
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
subroutine, public global_init(communicator)
Initialise Octopus.
Definition: global.F90:375
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_end()
Definition: io.F90:271
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
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 parser_init()
Initialise the Octopus parser.
Definition: parser.F90:410
subroutine, public parser_end()
End the Octopus parser.
Definition: parser.F90:442
subroutine, public profiling_end(namespace)
Definition: profiling.F90:415
subroutine, public profiling_init(namespace)
Create profiling subdirectory.
Definition: profiling.F90:257
This module defines routines to write information about states.
This module handles reading and writing restart information for the states_elec_t.
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.
subroutine, public unit_system_init(namespace)
type(unit_t), public unit_ev
For output energies in eV.
Interface module to Wannier 90 library.
subroutine, public wannier90lib_create_wannier90_amn(w90main, inp_options, exclude_list, band_index, space, mesh, latt, st, kpoints, projection)
Calculate wannier90 Projection Matrix.
subroutine, public wannier90lib_create_wannier90_mmn(w90main, exclude_list, band_index, mesh, st, ions, overlap)
Kohn-Sham State Overlap Matrix.
subroutine, public wannier90lib_init_w90main(namespace, ions, kpoints, st, inp_options, w90main, stdout, stderr, ierr)
Initialize wannier90 library data.
Wannier90 related calculations.
subroutine, public wannier_calc_load_restart(namespace, mc, space, st, gr, kpoints, restart_states)
Load Octopus restart data from disk.
Wannier options module.
Class describing the electron system.
Definition: electrons.F90:221
int true(void)
program wannier
Construct maximally-localised Wannier functions through API calls to Wannier90 library.
Definition: wannier.F90:107