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
30 implicit none
31
32 private
33 public :: &
34 ps_xml_t, &
37
38 type ps_xml_t
39 ! Components are public by default
40 logical :: initialized
41 logical :: kleinman_bylander
42 logical :: nlcc
43 logical :: has_density
44 integer :: atomic_number
45 real(real64) :: mass
46 real(real64) :: valence_charge
47 integer :: lmax
48 integer :: llocal
49 integer :: nchannels
50 integer :: grid_size
51 integer :: nwavefunctions
52 real(real64), allocatable :: grid(:)
53 real(real64), allocatable :: weights(:)
54 real(real64), allocatable :: potential(:, :)
55 real(real64), allocatable :: wavefunction(:, :)
56 real(real64), allocatable :: projector(:, :, :)
57 real(real64), allocatable :: dij(:, :, :)
58 real(real64), allocatable :: nlcc_density(:)
59 real(real64), allocatable :: density(:)
60 integer, allocatable :: wf_n(:)
61 integer, allocatable :: wf_l(:)
62 real(real64), allocatable :: wf_occ(:)
63 type(pseudo_t) :: pseudo
64 end type ps_xml_t
65
66contains
67
68 ! ---------------------------------------------------------
69 subroutine ps_xml_init(this, namespace, filename, fmt, ierr)
70 type(ps_xml_t), intent(inout) :: this
71 type(namespace_t), intent(in) :: namespace
72 character(len=*), intent(in) :: filename
73 integer, intent(in) :: fmt
74 integer, intent(out) :: ierr
75
76 integer :: ll, ii, ic, jc
77 type(pseudo_t) :: pseudo
78
79 push_sub(ps_xml_init)
80
81 this%initialized = .false.
82
83 call pseudo_init(pseudo, filename, fmt, ierr)
84
85 if (ierr == pseudo_status_file_not_found) then
86 call messages_write("Pseudopotential file '" // trim(filename) // "' not found")
87 call messages_fatal(namespace=namespace)
88 end if
89
90 if (ierr == pseudo_status_unknown_format) then
91 call messages_write("Cannot determine the format for pseudopotential file '" // trim(filename) // "'")
92 call messages_fatal(namespace=namespace)
93 end if
94
96 call messages_write("Ultrasoft pseudopotential file '" // trim(filename) // "' not supported")
97 call messages_fatal(namespace=namespace)
98 end if
99
100 if (ierr == pseudo_status_unsupported_type_paw) then
101 call messages_write("PAW pseudopotential file '" // trim(filename) // "' not supported")
102 call messages_fatal(namespace=namespace)
103 end if
104
105 if (ierr == pseudo_status_unsupported_type) then
106 call messages_write("Pseudopotential file '" // trim(filename) // "' not supported")
107 call messages_fatal(namespace=namespace)
108 end if
109
110 if (ierr == pseudo_status_format_not_supported) then
111 call messages_write("Pseudopotential file '" // trim(filename) // "' not supported")
112 call messages_fatal(namespace=namespace)
113 end if
115 this%initialized = .true.
116 this%valence_charge = pseudo_valence_charge(pseudo)
117 this%mass = pseudo_mass(pseudo)
118 this%lmax = pseudo_lmax(pseudo)
119 this%llocal = pseudo_llocal(pseudo)
120 this%nchannels = pseudo_nchannels(pseudo)
121
122 this%kleinman_bylander = (pseudo_type(pseudo) == pseudo_type_kleinman_bylander)
123
124 this%grid_size = pseudo_mesh_size(pseudo)
125
126 safe_allocate(this%grid(1:this%grid_size))
127 safe_allocate(this%weights(1:this%grid_size))
128
129 call pseudo_grid(pseudo, this%grid(1))
130 call pseudo_grid_weights(pseudo, this%weights(1))
132 if (.not. this%kleinman_bylander) then
134 safe_allocate(this%potential(1:this%grid_size, 0:this%lmax))
135 safe_allocate(this%wavefunction(1:this%grid_size, 0:this%lmax))
137 do ll = 0, this%lmax
138 if (.not. pseudo_has_radial_function(pseudo, ll)) then
139 call messages_write("The pseudopotential file '"//trim(filename)//"' does not contain")
141 call messages_write("the wave functions. Octopus cannot use it.")
142 call messages_fatal(namespace=namespace)
143 end if
145 call pseudo_radial_function(pseudo, ll, this%wavefunction(1, ll))
146 call pseudo_radial_potential(pseudo, ll, this%potential(1, ll))
147 end do
149 else
151 safe_allocate(this%potential(1:this%grid_size, this%llocal:this%llocal))
153 call pseudo_local_potential(pseudo, this%potential(1, this%llocal))
155 safe_allocate(this%projector(1:this%grid_size, 0:this%lmax, 1:this%nchannels))
157 this%projector = 0.0_real64
158
159 do ll = 0, this%lmax
160 if (this%llocal == ll) cycle
161 do ic = 1, pseudo_nprojectors_per_l(pseudo, ll)
162 call pseudo_projector(pseudo, ll, ic, this%projector(1, ll, ic))
163 end do
164 end do
165
166 safe_allocate(this%dij(0:this%lmax, 1:this%nchannels, 1:this%nchannels))
167
168 this%dij = 0.0_real64
169 do ll = 0, this%lmax
170 do ic = 1, this%nchannels
171 do jc = 1, this%nchannels
172 this%dij(ll, ic, jc) = pseudo_dij(pseudo, ll, ic, jc)
173 end do
174 end do
175 end do
176
177 this%nwavefunctions = pseudo_nwavefunctions(pseudo)
178
179 safe_allocate(this%wavefunction(1:this%grid_size, 1:this%nwavefunctions))
180 safe_allocate(this%wf_n(1:this%nwavefunctions))
181 safe_allocate(this%wf_l(1:this%nwavefunctions))
182 safe_allocate(this%wf_occ(1:this%nwavefunctions))
183
184 do ii = 1, this%nwavefunctions
185 call pseudo_wavefunction(pseudo, ii, this%wf_n(ii), this%wf_l(ii), this%wf_occ(ii), this%wavefunction(1, ii))
186 end do
187
188 end if
189
190 this%has_density = pseudo_has_density(pseudo)
191
192 if (this%has_density) then
193 safe_allocate(this%density(1:this%grid_size))
194 call pseudo_density(pseudo, this%density(1))
195 end if
196
197 this%nlcc = pseudo_has_nlcc(pseudo)
198 if (this%nlcc) then
199 safe_allocate(this%nlcc_density(1:this%grid_size))
200 call pseudo_nlcc_density(pseudo, this%nlcc_density(1))
201 end if
202
203 if (.not. this%kleinman_bylander) call ps_xml_check_normalization(this, namespace)
204
205 this%pseudo = pseudo
206
207 pop_sub(ps_xml_init)
208 end subroutine ps_xml_init
209
210 ! ---------------------------------------------------------
212 subroutine ps_xml_check_normalization(this, namespace)
213 type(ps_xml_t), intent(in) :: this
214 type(namespace_t), intent(in) :: namespace
215
216 integer :: ll, ip
217 real(real64) :: nrm, rr
218
220
221 ! checking normalization of the wavefunctions
222 do ll = 0, this%lmax
223 nrm = m_zero
224 do ip = 1, this%grid_size
225 rr = this%grid(ip)
226 nrm = nrm + this%wavefunction(ip, ll)**2*this%weights(ip)*rr**2
227 end do
228 nrm = sqrt(nrm)
229
230 nrm = abs(nrm - m_one)
231 if (nrm > 1.0e-5_real64) then
232 write(message(1), '(a,i2,a)') "Eigenstate for l = ", ll, ' is not normalized'
233 write(message(2), '(a, f12.6,a)') '(abs(1 - norm) = ', nrm, ')'
234 call messages_warning(2, namespace=namespace)
235 end if
236
237 end do
238
240 end subroutine ps_xml_check_normalization
241
242 ! ---------------------------------------------------------
243 subroutine ps_xml_end(this)
244 type(ps_xml_t), intent(inout) :: this
245
246 push_sub(ps_xml_end)
247
248 call pseudo_end(this%pseudo)
249
250 safe_deallocate_a(this%grid)
251 safe_deallocate_a(this%weights)
252 safe_deallocate_a(this%potential)
253 safe_deallocate_a(this%wavefunction)
254 safe_deallocate_a(this%projector)
255 safe_deallocate_a(this%dij)
256 safe_deallocate_a(this%nlcc_density)
257 safe_deallocate_a(this%density)
258 safe_deallocate_a(this%wf_n)
259 safe_deallocate_a(this%wf_l)
260 safe_deallocate_a(this%wf_occ)
261
262 pop_sub(ps_xml_end)
263 end subroutine ps_xml_end
264
265end module ps_xml_oct_m
266
267!! Local Variables:
268!! mode: f90
269!! coding: utf-8
270!! End:
double sqrt(double __x) __attribute__((__nothrow__
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_one
Definition: global.F90:188
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:543
subroutine, public messages_new_line()
Definition: messages.F90:1146
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:420
subroutine, public ps_xml_end(this)
Definition: ps_xml.F90:337
subroutine ps_xml_check_normalization(this, namespace)
checks normalization of the pseudo wavefunctions
Definition: ps_xml.F90:306
subroutine, public ps_xml_init(this, namespace, filename, fmt, ierr)
Definition: ps_xml.F90:163
integer, parameter, public pseudo_type_kleinman_bylander
Definition: pseudo.F90:158
logical function, public pseudo_has_radial_function(pseudo, l)
Definition: pseudo.F90:566
logical function, public pseudo_has_density(pseudo)
Definition: pseudo.F90:529
logical function, public pseudo_has_nlcc(pseudo)
Definition: pseudo.F90:511
integer, parameter, public pseudo_status_unsupported_type
Definition: pseudo.F90:164
integer, parameter, public pseudo_status_file_not_found
Definition: pseudo.F90:164
integer, parameter, public pseudo_status_unsupported_type_ultrasoft
Definition: pseudo.F90:164
integer, parameter, public pseudo_status_unknown_format
Definition: pseudo.F90:164
integer, parameter, public pseudo_status_unsupported_type_paw
Definition: pseudo.F90:164
integer, parameter, public pseudo_status_format_not_supported
Definition: pseudo.F90:164
int true(void)