Octopus
ps_xml.F90
Go to the documentation of this file.
1!! Copyright (C) 2015-2018 Xavier Andrade
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
21module ps_xml_oct_m
22 use debug_oct_m
23 use global_oct_m
24 use, intrinsic :: iso_fortran_env
28 use pseudo_oct_m
29 use string_oct_m
30
31 implicit none
32
33 private
34 public :: &
35 ps_xml_t, &
38
39 type ps_xml_t
40 ! Components are public by default
41 logical :: initialized
42 logical :: kleinman_bylander
43 logical :: nlcc
44 logical :: has_density
45 integer :: atomic_number
46 real(real64) :: mass
47 real(real64) :: valence_charge
48 integer :: lmax
49 integer :: llocal
50 integer :: nchannels
51 integer :: grid_size
52 integer :: nwavefunctions
53 real(real64), allocatable :: grid(:)
54 real(real64), allocatable :: weights(:)
55 real(real64), allocatable :: potential(:, :)
56 real(real64), allocatable :: wavefunction(:, :)
57 real(real64), allocatable :: projector(:, :, :)
58 real(real64), allocatable :: dij(:, :, :)
59 real(real64), allocatable :: qij(:, :, :)
60 logical :: has_qij_integrals
61 logical :: has_radial_augmentation
62 logical :: radial_augmentation_has_angular_channels
63 integer :: radial_augmentation_lmax
64 real(real64), allocatable :: radial_augmentation(:, :, :, :)
65 real(real64), allocatable :: nlcc_density(:)
66 real(real64), allocatable :: density(:)
67 integer, allocatable :: wf_n(:)
68 integer, allocatable :: wf_l(:)
69 real(real64), allocatable :: wf_occ(:)
70 type(pseudo_t) :: pseudo
71 integer, allocatable :: kb_radius(:,:)
72 end type ps_xml_t
73
74contains
75
76 ! ---------------------------------------------------------
77 subroutine ps_xml_init(this, namespace, filename, fmt, ierr)
78 type(ps_xml_t), intent(inout) :: this
79 type(namespace_t), intent(in) :: namespace
80 character(len=*), intent(in) :: filename
81 integer, intent(in) :: fmt
82 integer, intent(out) :: ierr
83
84 integer :: ll, ii, jj, ic, jc, ip, nproj
85 type(pseudo_t) :: pseudo
86
87 push_sub(ps_xml_init)
88
89 this%initialized = .false.
90
91 call pseudo_init(pseudo, string_f_to_c(filename), fmt, ierr)
92
93 if (ierr == pseudo_status_file_not_found) then
94 call messages_write("Pseudopotential file '" // trim(filename) // "' not found")
95 call messages_fatal(namespace=namespace)
96 end if
97
98 if (ierr == pseudo_status_unknown_format) then
99 call messages_write("Cannot determine the format for pseudopotential file '" // trim(filename) // "'")
100 call messages_fatal(namespace=namespace)
101 end if
102
104 call messages_write("Ultrasoft pseudopotential file '" // trim(filename) // "' not supported")
105 call messages_fatal(namespace=namespace)
106 end if
107
108 if (ierr == pseudo_status_unsupported_type_paw) then
109 call messages_write("PAW pseudopotential file '" // trim(filename) // "' not supported")
110 call messages_fatal(namespace=namespace)
111 end if
112
113 if (ierr == pseudo_status_unsupported_type) then
114 call messages_write("Pseudopotential file '" // trim(filename) // "' not supported")
115 call messages_fatal(namespace=namespace)
116 end if
117
118 if (ierr == pseudo_status_format_not_supported) then
119 call messages_write("Pseudopotential file '" // trim(filename) // "' not supported")
120 call messages_fatal(namespace=namespace)
121 end if
122
123 this%initialized = .true.
124 this%valence_charge = pseudo_valence_charge(pseudo)
125 this%mass = pseudo_mass(pseudo)
126 this%lmax = pseudo_lmax(pseudo)
127 this%llocal = pseudo_llocal(pseudo)
128 this%nchannels = pseudo_nchannels(pseudo)
129
130 this%kleinman_bylander = (pseudo_type(pseudo) == pseudo_type_kleinman_bylander .or. &
132 this%has_qij_integrals = pseudo_has_qij_integrals(pseudo)
133 if (pseudo_type(pseudo) == pseudo_type_ultrasoft .and. .not. this%has_qij_integrals) then
134 call messages_write("Ultrasoft pseudopotential file '" // trim(filename) // "' does not contain PP_Q or PP_QIJ")
135 call messages_fatal(namespace=namespace)
136 end if
137 this%has_radial_augmentation = pseudo_has_radial_augmentation(pseudo)
138 this%radial_augmentation_has_angular_channels = pseudo_radial_augmentation_has_angular_channels(pseudo)
139 this%radial_augmentation_lmax = pseudo_radial_augmentation_lmax(pseudo)
141 this%grid_size = pseudo_mesh_size(pseudo)
142 nproj = pseudo_nprojectors(pseudo)
144 safe_allocate(this%grid(1:this%grid_size))
145 safe_allocate(this%weights(1:this%grid_size))
147 call pseudo_grid(pseudo, this%grid(1))
148 call pseudo_grid_weights(pseudo, this%weights(1))
150 if (.not. this%kleinman_bylander) then
152 safe_allocate(this%potential(1:this%grid_size, 0:this%lmax))
153 safe_allocate(this%wavefunction(1:this%grid_size, 0:this%lmax))
155 do ll = 0, this%lmax
156 if (.not. pseudo_has_radial_function(pseudo, ll)) then
157 call messages_write("The pseudopotential file '"//trim(filename)//"' does not contain")
159 call messages_write("the wave functions. Octopus cannot use it.")
160 call messages_fatal(namespace=namespace)
161 end if
163 call pseudo_radial_function(pseudo, ll, this%wavefunction(1, ll))
164 call pseudo_radial_potential(pseudo, ll, this%potential(1, ll))
165 end do
166
167 else
168
169 safe_allocate(this%potential(1:this%grid_size, this%llocal:this%llocal))
171 call pseudo_local_potential(pseudo, this%potential(1, this%llocal))
172
173 safe_allocate(this%projector(1:this%grid_size, 0:this%lmax, 1:this%nchannels))
174
175 this%projector = m_zero
176
177 safe_allocate(this%kb_radius(0:this%lmax, 1:this%nchannels))
178 this%kb_radius = this%grid_size
179
180 do ll = 0, this%lmax
181 if (this%llocal == ll) cycle
182 do ic = 1, pseudo_nprojectors_per_l(pseudo, ll)
183 call pseudo_projector(pseudo, ll, ic, this%projector(1, ll, ic))
184
185 do ip = this%grid_size, 1, -1
186 if (abs(this%projector(ip, ll, ic)) > m_epsilon) then
187 this%kb_radius(ll, ic) = ip
188 exit
189 end if
190 end do
191 end do
192 end do
193
194 if (this%has_radial_augmentation) then
195 safe_allocate(this%radial_augmentation(1:this%grid_size, 1:nproj, 1:nproj, 0:this%radial_augmentation_lmax))
196
197 do ii = 1, nproj
198 do jj = 1, nproj
199 do ll = 0, this%radial_augmentation_lmax
200 call pseudo_radial_augmentation(pseudo, ii, jj, ll, this%radial_augmentation(1, ii, jj, ll))
201 end do
202 end do
203 end do
204 end if
205
206
207 safe_allocate(this%dij(0:this%lmax, 1:this%nchannels, 1:this%nchannels))
208 safe_allocate(this%qij(0:this%lmax, 1:this%nchannels, 1:this%nchannels))
209
210 this%dij = 0.0_real64
211 this%qij = 0.0_real64
212 do ll = 0, this%lmax
213 do ic = 1, this%nchannels
214 do jc = 1, this%nchannels
215 this%dij(ll, ic, jc) = pseudo_dij(pseudo, ll, ic, jc)
216 if (this%has_qij_integrals) this%qij(ll, ic, jc) = pseudo_qij(pseudo, ll, ic, jc)
217 end do
218 end do
219 end do
220
221 this%nwavefunctions = pseudo_nwavefunctions(pseudo)
222
223 safe_allocate(this%wavefunction(1:this%grid_size, 1:this%nwavefunctions))
224 safe_allocate(this%wf_n(1:this%nwavefunctions))
225 safe_allocate(this%wf_l(1:this%nwavefunctions))
226 safe_allocate(this%wf_occ(1:this%nwavefunctions))
227
228 do ii = 1, this%nwavefunctions
229 call pseudo_wavefunction(pseudo, ii, this%wf_n(ii), this%wf_l(ii), this%wf_occ(ii), this%wavefunction(1, ii))
230 end do
231
232 end if
233
234 this%has_density = pseudo_has_density(pseudo)
235
236 if (this%has_density) then
237 safe_allocate(this%density(1:this%grid_size))
238 call pseudo_density(pseudo, this%density(1))
239 end if
240
241 this%nlcc = pseudo_has_nlcc(pseudo)
242 if (this%nlcc) then
243 safe_allocate(this%nlcc_density(1:this%grid_size))
244 call pseudo_nlcc_density(pseudo, this%nlcc_density(1))
245 end if
246
247 if (.not. this%kleinman_bylander) call ps_xml_check_normalization(this, namespace)
248
249 this%pseudo = pseudo
250
251 pop_sub(ps_xml_init)
252 end subroutine ps_xml_init
253
254 ! ---------------------------------------------------------
256 subroutine ps_xml_check_normalization(this, namespace)
257 type(ps_xml_t), intent(in) :: this
258 type(namespace_t), intent(in) :: namespace
259
260 integer :: ll, ip
261 real(real64) :: nrm, rr
262
264
265 ! checking normalization of the wavefunctions
266 do ll = 0, this%lmax
267 nrm = m_zero
268 do ip = 1, this%grid_size
269 rr = this%grid(ip)
270 nrm = nrm + this%wavefunction(ip, ll)**2*this%weights(ip)*rr**2
271 end do
272 nrm = sqrt(nrm)
273
274 nrm = abs(nrm - m_one)
275 if (nrm > 1.0e-5_real64) then
276 write(message(1), '(a,i2,a)') "Eigenstate for l = ", ll, ' is not normalized'
277 write(message(2), '(a, f12.6,a)') '(abs(1 - norm) = ', nrm, ')'
278 call messages_warning(2, namespace=namespace)
279 end if
280
281 end do
282
284 end subroutine ps_xml_check_normalization
285
286 ! ---------------------------------------------------------
287 subroutine ps_xml_end(this)
288 type(ps_xml_t), intent(inout) :: this
289
290 push_sub(ps_xml_end)
291
292 call pseudo_end(this%pseudo)
293
294 safe_deallocate_a(this%grid)
295 safe_deallocate_a(this%weights)
296 safe_deallocate_a(this%potential)
297 safe_deallocate_a(this%wavefunction)
298 safe_deallocate_a(this%projector)
299 safe_deallocate_a(this%dij)
300 safe_deallocate_a(this%qij)
301 safe_deallocate_a(this%radial_augmentation)
302 safe_deallocate_a(this%nlcc_density)
303 safe_deallocate_a(this%density)
304 safe_deallocate_a(this%wf_n)
305 safe_deallocate_a(this%wf_l)
306 safe_deallocate_a(this%wf_occ)
307 safe_deallocate_a(this%kb_radius)
308
309 this%initialized = .false.
310
311 pop_sub(ps_xml_end)
312 end subroutine ps_xml_end
313
314end module ps_xml_oct_m
315
316!! Local Variables:
317!! mode: f90
318!! coding: utf-8
319!! End:
double sqrt(double __x) __attribute__((__nothrow__
real(real64), parameter, public m_zero
Definition: global.F90:198
real(real64), parameter, public m_epsilon
Definition: global.F90:214
real(real64), parameter, public m_one
Definition: global.F90:199
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:523
subroutine, public messages_new_line()
Definition: messages.F90:1087
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:408
/* To use the profiling module, call profiling_in and profiling_out with the label of the region as a...
Definition: profiling.F90:143
subroutine, public ps_xml_end(this)
Definition: ps_xml.F90:381
subroutine ps_xml_check_normalization(this, namespace)
checks normalization of the pseudo wavefunctions
Definition: ps_xml.F90:350
subroutine, public ps_xml_init(this, namespace, filename, fmt, ierr)
Definition: ps_xml.F90:171
integer, parameter, public pseudo_type_kleinman_bylander
Definition: pseudo.F90:164
logical function, public pseudo_has_radial_function(pseudo, l)
Definition: pseudo.F90:668
logical function, public pseudo_has_density(pseudo)
Definition: pseudo.F90:573
logical function, public pseudo_has_radial_augmentation(pseudo)
Definition: pseudo.F90:611
logical function, public pseudo_has_nlcc(pseudo)
Definition: pseudo.F90:555
integer, parameter, public pseudo_status_unsupported_type
Definition: pseudo.F90:170
integer, parameter, public pseudo_status_file_not_found
Definition: pseudo.F90:170
logical function, public pseudo_has_qij_integrals(pseudo)
Definition: pseudo.F90:592
integer, parameter, public pseudo_type_ultrasoft
Definition: pseudo.F90:164
integer, parameter, public pseudo_status_unsupported_type_ultrasoft
Definition: pseudo.F90:170
logical function, public pseudo_radial_augmentation_has_angular_channels(pseudo)
Definition: pseudo.F90:630
integer, parameter, public pseudo_status_unknown_format
Definition: pseudo.F90:170
integer, parameter, public pseudo_status_unsupported_type_paw
Definition: pseudo.F90:170
integer, parameter, public pseudo_status_format_not_supported
Definition: pseudo.F90:170
character(kind=c_char, len=1) function, dimension(:), allocatable, public string_f_to_c(f_string)
convert a Fortran string to a C string
Definition: string.F90:255
int true(void)