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 mesh_oct_m
27 use mpi_oct_m
31 use parser_oct_m
34 use space_oct_m
38 use unit_oct_m
42
43 ! External Wannier 90 library
44 use w90_library
45 use w90_library_extra, only:overlaps
46
47 implicit none
48
49 type(namespace_t) :: namespace
50 type(electrons_t), pointer :: sys
51 type(wan_opts_t) :: wan_opts
52 integer, allocatable :: band_index(:)
53
54 type(lib_common_type) :: w90main
55
56 complex(real64), allocatable :: m_matrix(:, :, :, :)
57 complex(real64), allocatable :: u_matrix(:, :, :)
58 complex(real64), allocatable :: u_matrix_opt(:, :, :)
59 real(real64), allocatable :: eigenvals(:,:)
60
61 integer, allocatable :: nnkp(:,:), gkpb(:,:,:)
62 logical, allocatable :: exclude_list(:)
63 integer :: nn
64
65 integer :: idir, ii, itemp, ik, ist
66
67 integer :: ierr
68 real(real64) :: factor(3)
69
70 ! Initialise all Octopus singletons
71 call global_init()
72 call parser_init()
73 call messages_init()
74 call io_init()
75 namespace = namespace_t("Wannier90Lib", parent = global_namespace)
76 call profiling_init(namespace)
77 call fft_all_init(namespace)
78 call unit_system_init(namespace)
79
80 ! Initialise a system object
81 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
82 sys => electrons_t(global_namespace, int(option__calculationmode__dummy, int32))
83 call sys%init_parallelization(mpi_world)
84
85 assert(sys%space%dim == 3)
86
87 ! Sanity checks
88 if (sys%kpoints%use_symmetries) then
89 message(1) = 'oct-wannier90: k-points symmetries are not allowed'
90 call messages_fatal(1)
91 end if
92 if (sys%kpoints%use_time_reversal) then
93 message(1) = 'oct-wannier90: time-reversal symmetry is not allowed'
94 call messages_fatal(1)
95 end if
96 if (sys%kpoints%reduced%nshifts > 1) then
97 message(1) = 'oct-wannier90: Wannier90 does not allow for multiple shifts of the k-point grid'
98 call messages_fatal(1)
99 end if
100 if (sys%st%d%nspin == 4) then
101 call messages_not_implemented('oct-wannier90: Spinors currently not supported', namespace)
102 end if
103
104 ! "Correct" rlattice/klattice for Wannier90 (3D periodicity assumed here).
105 ! Note: this is how the lattice is scaled in src/utils/wannier90_interface.F90
106 factor = m_one
107 do idir = sys%space%periodic_dim+1, sys%space%dim
108 factor(idir) = m_two * sys%gr%box%bounding_box_l(idir)
109 end do
110 call sys%ions%latt%scale(factor)
111
112 ! Parsing all input related to wannier90
113 call wan_opts_parse(namespace, wan_opts)
114
115 ! Initialize wannier90 lib object
116 call wannier90lib_init_w90main(namespace, sys%space, sys%gr, sys%ions, sys%kpoints, sys%st, &
117 wan_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_load_restart(global_namespace, sys%mc, sys%space, sys%st, sys%gr, sys%kpoints, wan_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(w90main%num_kpts, nn))
156 safe_allocate(gkpb(3, w90main%num_kpts, 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(wan_opts%num_bands, wan_opts%num_bands, nn, w90main%num_kpts))
162 safe_allocate(u_matrix_opt(wan_opts%num_bands, wan_opts%num_wann, w90main%num_kpts))
163 safe_allocate(eigenvals(wan_opts%num_bands, w90main%num_kpts))
164 safe_allocate(u_matrix(wan_opts%num_wann, wan_opts%num_wann, 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 (wan_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, wan_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 (wan_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
254
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:193
subroutine, public global_end()
Finalise parser varinfo file, and MPI.
Definition: global.F90:458
subroutine, public global_init(communicator)
Initialise Octopus.
Definition: global.F90:365
real(real64), parameter, public m_one
Definition: global.F90:192
This module implements the underlying real-space grid.
Definition: grid.F90:119
Definition: io.F90:116
subroutine, public io_init(defaults)
If the argument defaults is present and set to true, then the routine will not try to read anything f...
Definition: io.F90:165
subroutine, public io_end()
Definition: io.F90:271
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_end()
Definition: messages.F90:272
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1067
subroutine, public messages_init(output_dir)
Definition: messages.F90:219
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:524
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:161
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:409
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1039
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: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_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
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_init_w90main(namespace, space, mesh, ions, kpoints, st, wannier_opts, w90main, stdout, stderr, ierr)
Initialize wannier90 library data.
subroutine, public wannier90lib_create_wannier90_mmn(w90main, exclude_list, band_index, mesh, st, ions, overlap)
Kohn-Sham State Overlap Matrix.
subroutine, public wannier90lib_create_wannier90_amn(w90main, wan_opts, exclude_list, band_index, space, mesh, latt, st, kpoints, projection)
Calculate wannier90 Projection Matrix.
subroutine, public wan_opts_parse(namespace, wannier_opts)
Definition: wannier.F90:218
subroutine, public wannier_load_restart(namespace, mc, space, st, gr, kpoints, restart_states)
Load Octopus restart data from disk.
Definition: wannier.F90:182
Class describing the electron system.
Definition: electrons.F90:220
int true(void)
program wannier
Construct maximally-localised Wannier functions through API calls to Wannier90 library.
Definition: wannier.F90:107