2
! Copyright (C) 1996-2016 The SIESTA group
3
! This file is distributed under the terms of the
4
! GNU General Public License: see COPYING in the top directory
5
! or http://www.gnu.org/copyleft/gpl.txt .
6
! See Docs/Contributors.txt for a list of contributors.
10
! This module reads a pseudopotential file written in XML.
11
! A full example of the building up of a data structure using
15
use m_pseudo_types ! Data types
20
! It defines the routines that are called from xml_parser in response
21
! to particular events.
23
public :: begin_element, end_element, pcdata_chunk
26
logical, private :: in_vps = .false. , in_radfunc = .false.
27
logical, private :: in_semilocal = .false. , in_header = .false.
28
logical, private :: in_coreCharge = .false. , in_data = .false.
29
logical, private :: in_valenceCharge = .false.
30
logical, private :: in_pseudowavefun = .false. , in_pswf = .false.
32
integer, private, save :: ndata
34
type(pseudo_t), public, target, save :: pseudo
35
type(grid_t), private, save :: grid
36
type(grid_t), private, save :: global_grid
38
! Pointers to make it easier to manage the data
40
type(header_t), private, pointer :: hp
41
type(vps_t), private, pointer :: pp
42
type(pswf_t), private, pointer :: pw
43
type(radfunc_t), private, pointer :: rp
45
CONTAINS !===========================================================
47
!----------------------------------------------------------------------
48
subroutine begin_element(name,attributes)
49
character(len=*), intent(in) :: name
50
type(dictionary_t), intent(in) :: attributes
52
character(len=100) :: value
62
! call get_value(attributes,"version",value,status)
63
! if (value == "0.5") then
64
! print *, "Processing a PSEUDO version 0.5 XML file"
67
! global_grid%npts = 0
69
! print *, "Can only work with PSEUDO version 0.5 XML files"
77
call get_value(attributes,"symbol",hp%symbol,status)
78
if (status /= 0 ) call die("Cannot determine atomic symbol")
80
call get_value(attributes,"zval",value,status)
81
if (status /= 0 ) call die("Cannot determine zval")
82
read(unit=value,fmt=*) hp%zval
84
call get_value(attributes,"xc-functional-parametrization", &
85
hp%xcfunctionalparametrization,status)
87
call die("Cannot determine xc-functional-parametrization ")
89
call get_value(attributes,"creator",hp%creator,status)
90
if (status /= 0 ) hp%creator="unknown"
92
call get_value(attributes,"date",hp%date,status)
93
if (status /= 0 ) hp%date="unknown"
95
call get_value(attributes,"flavor",hp%flavor,status)
96
if (status /= 0 ) hp%flavor="unknown"
98
call get_value(attributes,"relativistic",value,status)
99
if (status /= 0 ) value = "no"
100
hp%relativistic = (value == "yes")
102
call get_value(attributes,"polarized",value,status)
103
if (status /= 0 ) value = "no"
104
hp%polarized = (value == "yes")
106
call get_value(attributes,"core-corrections", &
107
hp%core_corrections,status)
108
if (status /= 0 ) hp%core_corrections = "nc"
113
pseudo%npots = pseudo%npots + 1
114
pp => pseudo%pot(pseudo%npots)
115
rp => pp%V ! Pointer to radial function
117
call get_value(attributes,"l",pp%l,status)
118
if (status /= 0 ) call die("Cannot determine l for Vps")
120
call get_value(attributes,"principal-n",value,status)
121
if (status /= 0 ) call die("Cannot determine n for Vps")
122
read(unit=value,fmt=*) pp%n
124
call get_value(attributes,"cutoff",value,status)
125
if (status /= 0 ) call die("Cannot determine cutoff for Vps")
126
read(unit=value,fmt=*) pp%cutoff
128
call get_value(attributes,"occupation",value,status)
129
if (status /= 0 ) call die("Cannot determine occupation for Vps")
130
read(unit=value,fmt=*) pp%occupation
132
call get_value(attributes,"spin",value,status)
133
if (status /= 0 ) call die("Cannot determine spin for Vps")
134
read(unit=value,fmt=*) pp%spin
138
call get_value(attributes,"type",grid%type,status)
139
if (status /= 0 ) call die("Cannot determine grid type")
141
call get_value(attributes,"npts",value,status)
142
if (status /= 0 ) call die("Cannot determine grid npts")
143
read(unit=value,fmt=*) grid%npts
145
call get_value(attributes,"scale",value,status)
146
if (status /= 0 ) call die("Cannot determine grid scale")
147
read(unit=value,fmt=*) grid%scale
149
call get_value(attributes,"step",value,status)
150
if (status /= 0 ) call die("Cannot determine grid step")
151
read(unit=value,fmt=*) grid%step
154
! In this way we allow for a private grid for each radfunc,
155
! or for a global grid specification
165
if (rp%grid%npts == 0) STOP "Grid not specified correctly"
166
allocate(rp%data(rp%grid%npts))
167
ndata = 0 ! To start the build up
171
rp%grid = global_grid ! Might be empty
172
! There should then be a local grid element
175
case ("pseudocore-charge")
176
in_coreCharge = .true.
177
rp => pseudo%core_charge
179
case ("valence-charge")
180
in_valenceCharge = .true.
181
rp => pseudo%valence_charge
184
in_semilocal = .true.
186
call get_value(attributes,"npots-down",value,status)
187
if (status /= 0 ) call die("Cannot determine npots-down")
188
read(unit=value,fmt=*) pseudo%npots_down
190
call get_value(attributes,"npots-up",value,status)
191
if (status /= 0 ) call die("Cannot determine npots-up")
192
read(unit=value,fmt=*) pseudo%npots_up
194
case ("pseudowave-functions")
195
in_pseudowavefun = .true.
200
pseudo%npswfs = pseudo%npswfs + 1
202
pw => pseudo%pswf(pseudo%npswfs)
203
rp => pw%V ! Pointer to radial function
205
call get_value(attributes,"l",pw%l,status)
206
if (status /= 0 ) call die("Cannot determine l for Vps")
208
call get_value(attributes,"principal-n",value,status)
209
if (status /= 0 ) call die("Cannot determine n for Vps")
210
read(unit=value,fmt=*) pw%n
212
call get_value(attributes,"spin",value,status)
213
if (status /= 0 ) call die("Cannot determine spin for Vps")
214
read(unit=value,fmt=*) pw%spin
218
end subroutine begin_element
219
!----------------------------------------------------------------------
221
subroutine end_element(name)
222
character(len=*), intent(in) :: name
234
! We are done filling up the radfunc data
235
! Check that we got the advertised number of items
238
if (ndata /= size(rp%data)) STOP "npts mismatch"
240
case ("pseudocore-charge")
241
in_coreCharge = .false.
243
case ("valence-charge")
244
in_valenceCharge = .false.
247
in_semilocal = .false.
249
case ("pseudowave-functions")
250
in_pseudowavefun = .false.
256
! call dump_pseudo(pseudo)
260
end subroutine end_element
261
!----------------------------------------------------------------------
263
subroutine pcdata_chunk(chunk)
264
character(len=*), intent(in) :: chunk
267
if (len_trim(chunk) == 0) RETURN ! skip empty chunk
271
! Note that we know where we need to put it through the pointer rp...
273
call build_data_array(chunk,rp%data,ndata)
275
else if (in_header) then
277
! There should not be any pcdata in header in this version...
279
print *, "Header data:"
284
end subroutine pcdata_chunk
285
!----------------------------------------------------------------------
288
character(len=*), intent(in), optional :: str
289
if (present(str)) then
290
write(unit=0,fmt="(a)") trim(str)
292
write(unit=0,fmt="(a)") "Stopping Program"