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#include "global.h"
8
13module wannier_oct_m
14 use, intrinsic :: iso_fortran_env
15
16 use debug_oct_m
17 use global_oct_m
19 use io_oct_m
20 use ions_oct_m
22 use mesh_oct_m
24 use mpi_oct_m
28 use parser_oct_m
33 use types_oct_m
34 use unit_oct_m
37 only: &
43 use wfs_elec_oct_m, only: wfs_elec_t
45
46#ifdef HAVE_WANNIER90
47 use w90_library
49#endif
50
51 implicit none
52 private
53
54 public :: wannier_t
56 type :: wannier_t
57 type(wannier_opts_t) :: options
58 complex(real64), allocatable :: u_matrix(:,:,:)
59 complex(real64), allocatable :: u_dis_matrix(:,:,:)
60 real(real64), allocatable :: centers(:,:)
61#ifdef HAVE_WANNIER90
62 type(lib_common_type) :: w90main
63#endif
64
65 contains
66 procedure :: init_from_input => wannier_init_from_input
67 procedure :: init_parallelization => wannier_init_parallelization
68 procedure :: init_data_from_file => wannier_init_data_from_file
69 procedure :: restart_write_data => wannier_restart_write_data
70 procedure :: restart_read_data => wannier_restart_read_data
71 procedure :: write_iter => wannier_write_iter
72 final :: wannier_finalize
73 end type wannier_t
74
75contains
76
80 subroutine wannier_init_from_input(this, namespace, kpoints)
81 class(wannier_t), intent(inout) :: this
82 type(namespace_t), intent(in) :: namespace
83 type(kpoints_t), intent(in) :: kpoints
84
86
87 ! Parse all Wannier related options
88 call this%options%parse_oct(namespace)
89 if (this%options%td_method /= td_wannier_method_none) then
90 call this%options%parse_win()
91 end if
92
93 safe_allocate(this%u_matrix(1:this%options%num_wann, 1:this%options%num_wann, 1:product(kpoints%nik_axis)))
94 safe_allocate(this%u_dis_matrix(1:this%options%num_bands, 1:this%options%num_wann, 1:product(kpoints%nik_axis)))
95 safe_allocate(this%centers(1:3, 1:this%options%num_wann))
96 this%u_matrix = m_zero
97 this%u_dis_matrix = m_zero
98 this%centers = m_zero
99
101 end subroutine wannier_init_from_input
102
108 subroutine wannier_init_parallelization(this, namespace, st, ions, kpoints)
109 class(wannier_t), intent(inout) :: this
110 type(namespace_t), intent(in) :: namespace
111 type(states_elec_t), intent(in) :: st
112 type(ions_t), intent(in) :: ions
113 type(kpoints_t), intent(in) :: kpoints
114
115#ifdef HAVE_WANNIER90
116 integer :: ierr
117#endif
118
120#ifdef HAVE_WANNIER90
121 if (this%options%td_method /= td_wannier_method_none) then
122 call wannier90lib_init_w90main(namespace, ions, kpoints, st, &
123 this%options, this%w90main, stdout, stderr, ierr)
124 if (ierr /= 0) then
125 write(message(1),'(a,i0)') 'Error initializing wannier90 library object: ', ierr
126 call messages_fatal(1)
127 end if
128 end if
129#endif
130
132
133 end subroutine wannier_init_parallelization
134
139 subroutine wannier_init_data_from_file(this, kpoints, space)
140 class(wannier_t), intent(inout) :: this
141 type(kpoints_t), intent(in) :: kpoints
142 type(electron_space_t), intent(in) :: space
143
145
146 if (this%options%td_method /= td_wannier_method_none) then
147 if (space%dim /= 3) then ! see issue #1466
148 call messages_not_implemented("TD wannier: only 3D is supported")
149 end if
150 call wannier_calc_read_centers(this%options, this%centers)
151 call wannier_calc_read_u_matrices(this%options, kpoints, this%u_matrix, this%u_dis_matrix)
152 end if
153#ifdef HAVE_WANNIER90
154 call w90_set_u_matrix(this%w90main, this%u_matrix)
155 call w90_set_u_opt(this%w90main, this%u_dis_matrix)
156 this%w90main%wannier_data%centres = this%centers
157#endif
158
160 end subroutine wannier_init_data_from_file
166 subroutine wannier_restart_write_data(this, namespace, mc, gr)
167 class(wannier_t), intent(inout) :: this
168 type(namespace_t), intent(in) :: namespace
169 type(multicomm_t), intent(in) :: mc
170 class(mesh_t), intent(in) :: gr
171
172 type(restart_t) :: restart
173 integer :: ierr
174
176
177 call restart%init(namespace, restart_td, restart_type_dump, mc, ierr, mesh=gr)
178 if (ierr /= 0) then
179 message(1) = 'Unable to initialize TD restart for Wannier write.'
180 call messages_fatal(1)
181 end if
182
183 call restart%write_binary('wannier_u_matrix', size(this%u_matrix), this%u_matrix, ierr)
184 if (ierr /= 0) then
185 message(1) = 'Unable to write Wannier restart data (u_matrix).'
186 call messages_fatal(1)
187 end if
188
189 call restart%write_binary('wannier_u_dis_matrix', size(this%u_dis_matrix), this%u_dis_matrix, ierr)
190 if (ierr /= 0) then
191 message(1) = 'Unable to write Wannier restart data (u_dis_matrix).'
192 call messages_fatal(1)
193 end if
194
195 call restart%write_binary('wannier_centers', size(this%centers), this%centers, ierr)
196 if (ierr /= 0) then
197 message(1) = 'Unable to write Wannier restart data (centers).'
198 call messages_fatal(1)
199 end if
200
201 call restart%end()
202
204 end subroutine wannier_restart_write_data
205
210 subroutine wannier_restart_read_data(this, namespace, mc, gr)
211 class(wannier_t), intent(inout) :: this
212 type(namespace_t), intent(in) :: namespace
213 type(multicomm_t), intent(in) :: mc
214 class(mesh_t), intent(in) :: gr
215
216 type(restart_t) :: restart
217 integer :: ierr
218
220
221 call restart%init(namespace, restart_td, restart_type_load, mc, ierr, mesh=gr)
222 if (ierr /= 0) then
223 message(1) = 'Unable to initialize TD restart for Wannier read.'
225 end if
226
227 call restart%read_binary('wannier_u_matrix', size(this%u_matrix), this%u_matrix, ierr)
228 if (ierr /= 0) then
229 message(1) = 'Unable to read Wannier restart data (u_matrix).'
230 call messages_fatal(1)
231 end if
232
233 call restart%read_binary('wannier_u_dis_matrix', size(this%u_dis_matrix), this%u_dis_matrix, ierr)
234 if (ierr /= 0) then
235 message(1) = 'Unable to read Wannier restart data (u_dis_matrix).'
236 call messages_fatal(1)
237 end if
238
239 call restart%read_binary('wannier_centers', size(this%centers), this%centers, ierr)
240 if (ierr /= 0) then
241 message(1) = 'Unable to read Wannier restart data (centers).'
242 call messages_fatal(1)
243 end if
244
245#ifdef HAVE_WANNIER90
246 call w90_set_u_matrix(this%w90main, this%u_matrix)
247 call w90_set_u_opt(this%w90main, this%u_dis_matrix)
248 this%w90main%wannier_data%centres = this%centers
249#endif
250
251 call restart%end()
252
254 end subroutine wannier_restart_read_data
255
257 subroutine wannier_write_iter(this, namespace, outp, iter, ions, kpoints)
258 class(wannier_t), intent(in) :: this
259 type(namespace_t), intent(in) :: namespace
260 type(output_t), intent(inout) :: outp
261 integer, intent(in) :: iter
262 class(ions_t), intent(in) :: ions
263 type(kpoints_t), intent(in) :: kpoints
264
265 character(len=MAX_PATH_LEN) :: dir, raw_dir
266
267 push_sub(wannier_write_iter)
268
269 ! Only write wannier90 output every n iterations, as specified in input
270 if (mod(iter, this%options%td_output_interval) == 0) then
271 write(dir, '(a,a,i7.7)') trim(outp%iter_dir),"td.", iter ! name of directory
272 raw_dir = io_workpath(trim(dir), namespace)
273
274 call io_mkdir(trim(dir), namespace, parents=.true.)
275
276 if (this%options%td_method /= td_wannier_method_none) then
277 call wannier_calc_write_u_matrices(trim(raw_dir), trim(this%options%prefix), kpoints, this%u_matrix, this%u_dis_matrix)
278 call wannier_calc_write_centers(trim(raw_dir), trim(this%options%prefix), this%centers, ions)
279 end if
280 end if
281
282 pop_sub(wannier_write_iter)
283 end subroutine wannier_write_iter
284
286 subroutine wannier_finalize(wan)
287 type(wannier_t), intent(inout) :: wan
288
289 push_sub(wannier_finalize)
290
291 safe_deallocate_a(wan%u_matrix)
292 safe_deallocate_a(wan%u_dis_matrix)
293 safe_deallocate_a(wan%centers)
294#ifdef HAVE_WANNIER90
295 ! Attributes of `lib_common_type` are just pointers to memory we own, so no additional finalisation required
296#endif
297
298 pop_sub(wannier_finalize)
299 end subroutine wannier_finalize
300
301end module wannier_oct_m
real(real64), parameter, public m_zero
Definition: global.F90:200
Definition: io.F90:116
character(len=max_path_len) function, public io_workpath(path, namespace)
construct path name from given name and namespace
Definition: io.F90:318
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
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
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
this module contains the low-level part of the output system
Definition: output_low.F90:117
integer, parameter, public restart_type_dump
Definition: restart.F90:184
integer, parameter, public restart_td
Definition: restart.F90:156
integer, parameter, public restart_type_load
Definition: restart.F90:184
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.
Interface module to Wannier 90 library.
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_write_centers(dir, prefix, centers, ions)
Write wannier centers to file.
subroutine, public wannier_calc_read_centers(wan_opts, centers)
Read wannier centers.
subroutine, public wannier_calc_write_u_matrices(dir, prefix, kpoints, u_matrix, u_dis_matrix)
Write U and U_dis matrices to file.
subroutine, public wannier_calc_read_u_matrices(wan_opts, kpoints, u_matrix, u_dis_matrix)
Read wannier transformation matrix.
Wannier module.
Definition: wannier.F90:108
subroutine wannier_finalize(wan)
Clean up wannier object data.
Definition: wannier.F90:372
subroutine wannier_restart_write_data(this, namespace, mc, gr)
Write TD Wannier restart data.
Definition: wannier.F90:252
subroutine wannier_write_iter(this, namespace, outp, iter, ions, kpoints)
Write TD Wannier data every n time steps.
Definition: wannier.F90:343
subroutine wannier_init_data_from_file(this, kpoints, space)
Initialize wannier object data for TD run.
Definition: wannier.F90:225
subroutine wannier_restart_read_data(this, namespace, mc, gr)
Read TD Wannier restart data.
Definition: wannier.F90:296
subroutine wannier_init_from_input(this, namespace, kpoints)
Initialize wannier object options from input files.
Definition: wannier.F90:176
subroutine wannier_init_parallelization(this, namespace, st, ions, kpoints)
Initialize parallelization for wannier object.
Definition: wannier.F90:204
Wannier options module.
integer, parameter, public td_wannier_method_none
Describes mesh distribution to nodes.
Definition: mesh.F90:187
Stores all communicators and groups.
Definition: multicomm.F90:208
output handler class
Definition: output_low.F90:166
Main object containing all Wannier-related data and methods.
Definition: wannier.F90:151
batches of electronic states
Definition: wfs_elec.F90:141
int true(void)