Octopus
isdf_utils.F90
Go to the documentation of this file.
1!! Copyright (C) 2025. Alexander Buccheri
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, U
17
18#include "global.h"
19
21 use, intrinsic :: iso_fortran_env, only: real64, int64
22 use batch_oct_m, only: batch_packed
23 use comm_oct_m, only: comm_allreduce
24 use debug_oct_m
25 use global_oct_m
26 use io_oct_m, only: io_open, io_close
29 use mpi_oct_m, only: mpi_world
34
35 implicit none
36
37 private
38 public :: &
44
45 ! TODO(Alex) Issue #1195 Extend ISDF to spin-polarised systems
47 integer, private, parameter :: ik = 1
48
49contains
50
52 subroutine output_matrix(namespace, fname, matrix)
53 type(namespace_t), intent(in) :: namespace
54 character(len=*), intent(in) :: fname
55 real(real64), contiguous, intent(in) :: matrix(:, :)
56
57 integer :: i, j, unit
58
59 push_sub(output_matrix)
60
61 write(message(1),'(a)') "ISDF. Outputting: " // trim(adjustl(fname))
62 call messages_info(1, namespace=namespace, debug_only=.true.)
63
64 if (mpi_world%is_root()) then
65
66 open(newunit=unit, file=trim(adjustl(fname)))
67 do j = 1, size(matrix, 2)
68 do i = 1, size(matrix, 1)
69 write(unit, *) matrix(i, j)
70 enddo
71 enddo
72 close(unit)
73
74 endif
75
76 pop_sub(output_matrix)
77
78 end subroutine output_matrix
79
86 subroutine isdf_potential(namespace, poisson_solver, isdf_vectors, V_r_nu)
87 type(namespace_t), intent(in ) :: namespace
88 type(poisson_t), intent(in ) :: poisson_solver
89 real(real64), intent(in ), contiguous :: isdf_vectors(:, :)
90
91 real(real64), intent(out), contiguous :: V_r_nu(:, :)
92
93 integer :: i_nu
94
95 push_sub_with_profile(isdf_potential)
96
97 ! Construct V_mu(r) = \int K(r, r^\prime) \zeta_mu(r^\prime) dr^\prime
98 do i_nu = 1, size(v_r_nu, 2)
99 call dpoisson_solve(poisson_solver, namespace, v_r_nu(:, i_nu), isdf_vectors(:, i_nu), all_nodes=.false.)
100 enddo
101
102 pop_sub_with_profile(isdf_potential)
103
104 end subroutine isdf_potential
105
106
112 integer function local_number_of_states(st, max_state)
113 type(states_elec_t), intent(in) :: st
114 integer, intent(in) :: max_state
116 integer :: minst, maxst
117
118 push_sub(local_number_of_states)
119
120 minst = states_elec_block_min(st, st%group%block_start)
121 maxst = min(states_elec_block_max(st, st%group%block_end), max_state)
122
123 ! Handles when max_state is part of a block with index < (block_start of current process)
124 ! resulting in no states on this process being used in the ISDF expansion
125 local_number_of_states = max(maxst - minst + 1, 0)
126
128
129 end function local_number_of_states
130
131
136 subroutine gather_psi_mu_over_states(st, psi_mu, psi_global)
137 type(states_elec_t), intent(in ) :: st
138 real(real64), contiguous, intent(in ) :: psi_mu(:, :)
139 real(real64), contiguous, intent(out) :: psi_global(:, :)
140
141 integer :: max_state, n_int_g, ic, ist, st_end, ist_local
144
145 if (st%group%psib(st%group%block_start, ik)%status() /= batch_packed) then
146 message(1) = "Developer Error: Trying to output psi_mu when not BATCH_PACKED"
148 endif
149
150 ! Total number of interpolation points
151 n_int_g = size(psi_global, 2)
152 assert(size(psi_mu, 2) == size(psi_global, 2))
153
154 ! Total number of states used in ISDF
155 max_state = size(psi_global, 1)
156
157 ! All elements must be zeroed, such that allreduce does not
158 ! sum contributions from uninitialised elements
159 do ic = 1, n_int_g
160 do ist = 1, max_state
161 psi_global(ist, ic) = 0.0_real64
162 enddo
163 enddo
164
165 ! Ensure states does not iterate beyond the max state used in
166 ! ISDF expansion
167 st_end = min(st%st_end, max_state)
168
169 ! Sanity check on number of local states held by psi_mu
170 if (size(psi_mu, 1) > 0) then
171 assert(st_end - st%st_start + 1 == size(psi_mu, 1))
172 endif
173
174 ! Fill a section of psi_global using psi_mu
175 do ic = 1, n_int_g
176 do ist = st%st_start, st_end
177 ist_local = ist - st%st_start + 1
178 psi_global(ist, ic) = psi_mu(ist_local, ic)
179 enddo
180 enddo
182 call comm_allreduce(st%mpi_grp, psi_global)
183
185
186 end subroutine gather_psi_mu_over_states
187
188
191 subroutine output_psi_mu_for_all_states(namespace, st, max_state, psi_mu)
192 type(namespace_t), intent(in) :: namespace
193 type(states_elec_t), intent(in) :: st
194 integer, intent(in) :: max_state
195 real(real64), contiguous, intent(in) :: psi_mu(:, :)
196
197 real(real64), allocatable :: psi_global(:, :)
198 integer :: n_int_g, ic, ist, unit
199 character(len=2) :: np_char
200
202
203 if (st%group%psib(st%group%block_start, ik)%status() /= batch_packed) then
204 message(1) = "Trying to output psi_mu when not BATCH_PACKED"
205 call messages_fatal(1, namespace=namespace)
206 endif
208 write(message(1),'(a)') "ISDF: Writing psi_mu (all states/DD)"
209 call messages_info(1)
210
211 n_int_g = size(psi_mu, 2)
212 safe_allocate(psi_global(1:max_state, 1:n_int_g))
213
214 call gather_psi_mu_over_states(st, psi_mu, psi_global)
215
216 write(np_char, '(I2)') st%mpi_grp%size
217 unit = io_open("global_psi_mu_np"//trim(adjustl(np_char))//".txt", namespace, action='write')
218
219 do ic = 1, n_int_g
220 do ist = 1, max_state
221 write(unit, *) psi_global(ist, ic)
222 enddo
223 enddo
224
225 call io_close(unit)
226
227 safe_deallocate_a(psi_global)
228
230
232
233
234end module isdf_utils_oct_m
235
236!! Local Variables:
237!! mode: f90
238!! coding: utf-8
239!! End:
This module implements batches of mesh functions.
Definition: batch.F90:135
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
Definition: batch.F90:286
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:466
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:401
subroutine, public output_matrix(namespace, fname, matrix)
Helper routine to output a 2D matrix.
Definition: isdf_utils.F90:148
subroutine, public isdf_potential(namespace, poisson_solver, isdf_vectors, V_r_nu)
Compute the effective potential in the ISDF vector basis.
Definition: isdf_utils.F90:182
integer function, public local_number_of_states(st, max_state)
Number of states contributing to the expansion, local to current process.
Definition: isdf_utils.F90:208
subroutine, public output_psi_mu_for_all_states(namespace, st, max_state, psi_mu)
Output the gathered psi_mu for all states, such that the matrix is the same irregardless of state par...
Definition: isdf_utils.F90:287
subroutine, public gather_psi_mu_over_states(st, psi_mu, psi_global)
Gather state-distributed psi from multiple processes.
Definition: isdf_utils.F90:232
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:416
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:600
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
subroutine, public dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Calculates the Poisson equation. Given the density returns the corresponding potential.
Definition: poisson.F90:871
integer pure function, public states_elec_block_max(st, ib)
return index of last state in block ib
integer pure function, public states_elec_block_min(st, ib)
return index of first state in block ib
The states_elec_t class contains all electronic wave functions.
int true(void)