New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
m_pseudo.f90 in vendors/XMLF90/current/doc/Examples/sax/pseudo – NEMO

source: vendors/XMLF90/current/doc/Examples/sax/pseudo/m_pseudo.f90 @ 1963

Last change on this file since 1963 was 1963, checked in by flavoni, 14 years ago

importing XMLF90 r_53 vendor

File size: 7.3 KB
Line 
1module m_pseudo
2!
3!  PSEUDO version 0.5 processing
4!  A full example of the building up of a data structure using
5!  the SAX paradigm.
6!
7use flib_sax
8use m_pseudo_types         ! Data types
9
10private
11
12!
13! It defines the routines that are called from xml_parser in response
14! to particular events.
15!
16public  :: begin_element, end_element, pcdata_chunk
17private :: die
18
19logical, private  :: in_vps = .false. , in_radfunc = .false.
20logical, private  :: in_semilocal = .false. , in_header = .false.
21logical, private  :: in_coreCharge = .false. , in_data = .false.
22logical, private  :: in_valenceCharge = .false.
23
24integer, private, save  :: ndata
25
26type(pseudo_t), private, target, save :: pseudo
27type(grid_t), private, save        :: grid
28type(grid_t), private, save        :: global_grid
29!
30! Pointers to make it easier to manage the data
31!
32type(header_t), private, pointer   :: hp
33type(vps_t), private, pointer      :: pp
34type(radfunc_t), private, pointer  :: rp
35
36CONTAINS  !===========================================================
37
38!----------------------------------------------------------------------
39subroutine begin_element(name,attributes)
40character(len=*), intent(in)    :: name
41type(dictionary_t), intent(in)  :: attributes
42
43character(len=100)  :: value
44integer             :: status
45
46
47select case(name)
48
49      case ("pseudo")
50         call get_value(attributes,"version",value,status)
51         if (value == "0.5") then
52            print *, "Processing a PSEUDO version 0.5 XML file"
53            pseudo%npots = 0
54            global_grid%npts = 0
55         else
56            print *, "Can only work with PSEUDO version 0.5 XML files"
57            STOP
58         endif
59
60      case ("header")
61         in_header = .true.
62         hp => pseudo%header
63         
64         call get_value(attributes,"symbol",hp%symbol,status)
65         if (status /= 0 ) call die("Cannot determine atomic symbol")
66
67         call get_value(attributes,"zval",value,status)
68         if (status /= 0 ) call die("Cannot determine zval")
69         read(unit=value,fmt=*) hp%zval
70!
71         call get_value(attributes,"creator",hp%creator,status)
72         if (status /= 0 ) hp%creator="unknown"
73
74         call get_value(attributes,"flavor",hp%flavor,status)
75         if (status /= 0 ) hp%flavor="unknown"
76
77         call get_value(attributes,"relativistic",value,status)
78         if (status /= 0 ) value = "no"
79         hp%relativistic = (value == "yes")
80
81         call get_value(attributes,"polarized",value,status)
82         if (status /= 0 ) value = "no"
83         hp%polarized = (value == "yes")
84
85         call get_value(attributes,"core-corrections", &
86                                    hp%core_corrections,status)
87         if (status /= 0 ) hp%core_corrections = "nc"
88
89      case ("vps")
90         in_vps = .true.
91
92         pseudo%npots = pseudo%npots + 1
93         pp => pseudo%pot(pseudo%npots)
94         rp => pp%V                       ! Pointer to radial function
95
96         call get_value(attributes,"l",value,status)
97         if (status /= 0 ) call die("Cannot determine l for Vps")
98         read(unit=value,fmt=*) pp%l
99
100         call get_value(attributes,"principal-n",value,status)
101         if (status /= 0 ) call die("Cannot determine n for Vps")
102         read(unit=value,fmt=*) pp%n
103
104         call get_value(attributes,"cutoff",value,status)
105         if (status /= 0 ) call die("Cannot determine cutoff for Vps")
106         read(unit=value,fmt=*) pp%cutoff
107
108         call get_value(attributes,"occupation",value,status)
109         if (status /= 0 ) call die("Cannot determine occupation for Vps")
110         read(unit=value,fmt=*) pp%occupation
111
112         call get_value(attributes,"spin",value,status)
113         if (status /= 0 ) call die("Cannot determine spin for Vps")
114         read(unit=value,fmt=*) pp%spin
115
116      case ("grid")
117
118         call get_value(attributes,"type",grid%type,status)
119         if (status /= 0 ) call die("Cannot determine grid type")
120
121         call get_value(attributes,"npts",value,status)
122         if (status /= 0 ) call die("Cannot determine grid npts")
123         read(unit=value,fmt=*) grid%npts
124
125         call get_value(attributes,"scale",value,status)
126         if (status /= 0 ) call die("Cannot determine grid scale")
127         read(unit=value,fmt=*) grid%scale
128
129         call get_value(attributes,"step",value,status)
130         if (status /= 0 ) call die("Cannot determine grid step")
131         read(unit=value,fmt=*) grid%step
132
133         !
134         ! In this way we allow for a private grid for each radfunc,
135         ! or for a global grid specification
136         !
137         if (in_radfunc) then
138            rp%grid = grid
139         else
140            global_grid = grid
141         endif
142
143      case ("data")
144         in_data = .true.
145         if (rp%grid%npts == 0) STOP "Grid not specified correctly"
146         allocate(rp%data(rp%grid%npts))
147         ndata = 0             ! To start the build up
148
149      case ("radfunc")
150         in_radfunc = .true.
151         rp%grid = global_grid     ! Might be empty
152                                   ! There should then be a local grid element
153                                   ! read later
154
155      case ("pseudocore-charge")
156         in_coreCharge = .true.
157         rp => pseudo%core_charge
158
159      case ("valence-charge")
160         in_valenceCharge = .true.
161         rp => pseudo%valence_charge
162
163      case ("semilocal")
164         in_semilocal = .true.
165
166         call get_value(attributes,"npots-down",value,status)
167         if (status /= 0 ) call die("Cannot determine npots-down")
168         read(unit=value,fmt=*) pseudo%npots_down
169
170         call get_value(attributes,"npots-up",value,status)
171         if (status /= 0 ) call die("Cannot determine npots-up")
172         read(unit=value,fmt=*) pseudo%npots_up
173
174end select
175
176end subroutine begin_element
177!----------------------------------------------------------------------
178
179subroutine end_element(name)
180character(len=*), intent(in)     :: name
181
182select case(name)
183
184      case ("vps")
185         in_vps = .false.
186
187      case ("radfunc")
188         in_radfunc = .false.
189
190      case ("data")
191      !
192      ! We are done filling up the radfunc data
193      ! Check that we got the advertised number of items
194      !
195         in_data = .false.
196         if (ndata /= size(rp%data)) STOP "npts mismatch"
197
198      case ("pseudocore-charge")
199         in_coreCharge = .false.
200
201      case ("valence-charge")
202         in_valenceCharge = .false.
203
204      case ("semilocal")
205         in_semilocal = .false.
206
207      case ("pseudo")
208         call dump_pseudo(pseudo)
209
210end select
211
212end subroutine end_element
213!----------------------------------------------------------------------
214
215subroutine pcdata_chunk(chunk)
216character(len=*), intent(in) :: chunk
217
218
219if (len_trim(chunk) == 0) RETURN     ! skip empty chunk
220
221if (in_data) then
222!
223! Note that we know where we need to put it through the pointer rp...
224!
225      call build_data_array(chunk,rp%data,ndata)
226
227else if (in_header) then
228      !
229      ! There should not be any pcdata in header in this version...
230
231      print *, "Header data:"
232      print *, trim(chunk)
233
234endif
235
236end subroutine pcdata_chunk
237!----------------------------------------------------------------------
238
239      subroutine die(str)
240      character(len=*), intent(in), optional   :: str
241      if (present(str)) then
242         write(unit=0,fmt="(a)") trim(str)
243      endif
244      write(unit=0,fmt="(a)") "Stopping Program"
245      stop
246      end subroutine die
247
248
249end module m_pseudo
250
251
252
253
254
255
256
257
258
259
260
261
Note: See TracBrowser for help on using the repository browser.