Line data Source code
1 : !!****m* ABINIT/m_outxml
2 : !! NAME
3 : !! m_outxml
4 : !!
5 : !! FUNCTION
6 : !!
7 : !! COPYRIGHT
8 : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR)
9 : !! This file is distributed under the terms of the
10 : !! GNU General Public License, see ~abinit/COPYING
11 : !! or http://www.gnu.org/copyleft/gpl.txt.
12 : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_outxml
23 :
24 : use defs_basis
25 : use m_abicore
26 : use m_errors
27 : use m_dtset
28 :
29 : use m_io_tools, only : open_file
30 : use m_geometry, only : xcart2xred, xred2xcart
31 : use m_results_gs , only : results_gs_type
32 :
33 : implicit none
34 :
35 : private
36 :
37 : public :: outxml_open
38 : public :: outxml_finalise
39 : public :: out_resultsgs_XML
40 : public :: out_geometry_XML
41 : !!***
42 :
43 : contains
44 :
45 : !!****f* m_outxml/outxml_open
46 : !! NAME
47 : !! outxml_open
48 : !!
49 : !! FUNCTION
50 : !! Open the XML log file, and write the header inside.
51 : !! (see extras/post_processing/abinitRun.dtd)
52 : !! Warning: this method is not thread safe and should be called only by one thread.
53 : !!
54 : !! INPUTS
55 : !! filename=the name of the file to write to.
56 : !!
57 : !! SOURCE
58 :
59 1 : subroutine outxml_open(filename)
60 :
61 : !Arguments -------------------------------
62 : character(len = *), intent(in) :: filename
63 : !Local variables -------------------------
64 : character(len=500) :: msg
65 :
66 : ! *********************************************************************
67 :
68 : !ABINIT has been compiled with XML output support, then we open the
69 : !channel of the XML output file.
70 1 : if (open_file(trim(filename)//"_LOG.xml", msg, unit=ab_xml_out, form="formatted", action="write") /= 0) then
71 0 : ABI_ERROR(msg)
72 : end if
73 :
74 1 : write(ab_xml_out, "(A)") '<?xml version="1.0" encoding="utf-8"?>'
75 : !DTD declaration : root element is "abinitRun", and DTD file is not public
76 : !but given in the distribution by the file abinitRun.dtd.
77 1 : write(ab_xml_out, "(A)") '<!DOCTYPE abinitRun SYSTEM "extras/post_processing/abinitRun.dtd">'
78 : !Creating the root markup.
79 1 : write(ab_xml_out, "(A)") '<abinitRun>'
80 :
81 1 : end subroutine outxml_open
82 : !!***
83 :
84 : !!****f* m_outxml/outxml_finalise
85 : !!
86 : !! NAME
87 : !! outxml_finalise
88 : !!
89 : !! FUNCTION
90 : !! Close the XML log file, and write the timing information.
91 : !! (see extras/post_processing/abinitRun.dtd)
92 : !! Warning : this method is not thread safe and should be called
93 : !! only by one thread.
94 : !!
95 : !! INPUTS
96 : !! tsec=the cpu time and the wall time in seconds.
97 : !! values=the date values returned by date_and_time() intrinsic Fortran routine.
98 : !!
99 : !! SOURCE
100 :
101 1 : subroutine outxml_finalise(tsec, values)
102 :
103 : !Arguments -------------------------------
104 : integer, intent(in) :: values(8)
105 : real(dp), intent(in) :: tsec(2)
106 : !Local variables -------------------------
107 : character(len=500) :: message
108 :
109 : ! *********************************************************************
110 :
111 1 : write(ab_xml_out, "(A)") ' <!-- timeInfo markup : cpu and wall attributes are given in seconds. -->'
112 : write(ab_xml_out, "(A,I0,A,I0,A,I0,A)", advance = "NO") &
113 1 : & ' <timeInfo day="', values(3) , &
114 2 : & '" month="', values(2) ,'" year="', values(1) ,'" '
115 1 : write(message, *) tsec(1)
116 1 : write(ab_xml_out, "(A,A,A)", advance = "NO") 'cpu="', trim(message) ,'"'
117 1 : write(message, *) tsec(2)
118 1 : write(ab_xml_out, "(A,A,A)") ' wall="', trim(message) ,'" />'
119 1 : write(ab_xml_out, "(A)") "</abinitRun>"
120 : !ABINIT has been compiled with XML output support, then we close the channel of the XML output file.
121 1 : close(unit = ab_xml_out)
122 :
123 1 : end subroutine outxml_finalise
124 : !!***
125 :
126 : !!****f* m_outxml/out_resultsgs_xml
127 : !!
128 : !! NAME
129 : !! out_resultsgs_xml
130 : !!
131 : !! FUNCTION
132 : !! Output in the XML file, the decomposition of the energy and
133 : !! the forces after a scfcv loop.
134 : !! (see extras/post_processing/abinitRun.dtd)
135 : !! Warning : this method is not thread safe and should be called only by one thread.
136 : !!
137 : !! INPUTS
138 : !! dtset <type(dataset_type)>=all input variables for this dataset
139 : !! level=use for indentation of the XML, two spaces are added by level.
140 : !! results_gs <type(results_gs_type)>=results (energy and its components,
141 : !! forces and its components, the stress tensor) of a ground-state computation.
142 : !! usepaw= 0 for non paw calculation; =1 for paw calculation
143 : !!
144 : !! SOURCE
145 :
146 4 : subroutine out_resultsgs_XML(dtset, level, results_gs, usepaw)
147 :
148 : !Arguments ------------------------------------
149 : !scalars
150 : integer,intent(in) :: level,usepaw
151 : type(dataset_type),intent(in) :: dtset
152 : type(results_gs_type),intent(inout) :: results_gs
153 :
154 : !Local variables -------------------------
155 : character(len = 1), parameter :: axes_names(3) = (/ "x", "y", "z" /)
156 : !scalars
157 : integer :: i,j
158 : character(len=128) :: spacer,value
159 :
160 : ! *************************************************************************
161 :
162 : !Compute the spacer to put before each markup
163 4 : write(spacer, "(A,I0)") "A", 2 * level
164 :
165 : !Begin with the energy part
166 4 : write(ab_xml_out, "("//trim(spacer)//",A)", advance = "NO") " ", '<energy'
167 4 : if (dtset%iscf < 10) then
168 4 : write(ab_xml_out, "(A)", advance = "NO") ' type="direct"'
169 4 : write(value, "(es20.8)") results_gs%energies%e_kinetic
170 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' kinetic="', trim(value) ,'"'
171 4 : write(value, "(es20.8)") results_gs%energies%e_localpsp
172 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' local="', trim(value) ,'"'
173 4 : write(value, "(es20.8)") results_gs%energies%e_nlpsp_vfock
174 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' non-local="', trim(value) ,'"'
175 4 : if (usepaw == 1) then
176 0 : write(value, "(es20.8)") results_gs%energies%paw%epaw
177 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' paw="', trim(value) ,'"'
178 : end if
179 : else
180 0 : write(ab_xml_out, "(A)", advance = "NO") ' type="double-counting"'
181 0 : write(value, "(es20.8)") results_gs%energies%e_eigenvalues
182 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' eigen-values="', trim(value) ,'"'
183 0 : write(value, "(es20.8)") results_gs%energies%e_xcdc
184 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' xcdc="', trim(value) ,'"'
185 0 : if (usepaw == 1) then
186 0 : write(value, "(es20.8)") results_gs%energies%paw%epaw_dc
187 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' pawdc="', trim(value) ,'"'
188 : end if
189 : end if
190 : if (dtset%berryopt == 4 .or. dtset%berryopt == 6 .or. dtset%berryopt == 7 .or. &
191 4 : & dtset%berryopt ==14 .or. dtset%berryopt ==16 .or. dtset%berryopt ==17) then
192 0 : write(value, "(es20.8)") results_gs%energies%e_elecfield
193 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' electric-field="', trim(value) ,'"'
194 : end if
195 4 : if(dtset%occopt >= 3 .and. dtset%occopt <= 8) then
196 0 : write(value, "(es20.8)") results_gs%energies%e_entropy
197 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' entropy="', trim(value) ,'"'
198 : end if
199 4 : write(value, "(es20.8)") results_gs%energies%e_ewald
200 4 : if (dtset%icoulomb == 0) then
201 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' ewald="', trim(value) ,'"'
202 : else
203 0 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' ion-ion="', trim(value) ,'"'
204 : end if
205 4 : write(value, "(es20.8)") results_gs%energies%e_chempot
206 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' chempot="', trim(value) ,'"'
207 4 : write(value, "(es20.8)") results_gs%energies%e_hartree
208 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' hartree="', trim(value) ,'"'
209 4 : write(value, "(es20.8)") results_gs%energies%e_corepsp
210 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' core="', trim(value) ,'"'
211 4 : write(value, "(es20.8)") results_gs%energies%e_xc
212 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' xc="', trim(value) ,'"'
213 4 : write(value, "(es20.8)") results_gs%etotal
214 4 : write(ab_xml_out, "(A,A,A)", advance = "NO") ' total="', trim(value) ,'"'
215 4 : write(ab_xml_out, "(A)") ' />'
216 :
217 :
218 : !finish with the forces part
219 4 : if (dtset%optforces == 1) then
220 0 : write(ab_xml_out, "("//trim(spacer)//",A)") " ", '<forces>'
221 0 : do i = 1, dtset%natom, 1
222 0 : write(ab_xml_out, "("//trim(spacer)//",A)", advance = "NO") " ", ' <force'
223 0 : write(ab_xml_out, "(A,I0,A,I0,A)", advance = "NO") ' atom="a_', dtset%jdtset ,'_', i ,'"'
224 0 : do j = 1, 3, 1
225 0 : write(value, "(es20.8)") results_gs%fcart(j, i)
226 0 : write(ab_xml_out, "(A,A,A,A,A)", advance = "NO") ' ', axes_names(j), '="', trim(value) ,'"'
227 : end do
228 0 : write(ab_xml_out, "(A)") ' />'
229 : end do
230 0 : write(ab_xml_out, "("//trim(spacer)//",A)") " ", '</forces>'
231 : end if
232 :
233 4 : end subroutine out_resultsgs_XML
234 : !!***
235 :
236 : !!****f* m_outxml/out_geometry_xml
237 : !!
238 : !! NAME
239 : !! out_geometry_xml
240 : !!
241 : !! FUNCTION
242 : !! Output in the XML file, the box size and the atomic position.
243 : !! (see extras/post_processing/abinitRun.dtd)
244 : !!
245 : !! INPUTS
246 : !! dtset <type(dataset_type)>=all input variables for this dataset
247 : !! level=use for indentation of the XML, two spaces are added by level.
248 : !! natom=number of atoms.
249 : !! rprimd(3,3)=dimensional primitive translations in real space (bohr)
250 : !! xred(3,natom)=reduced dimensionless atomic coordinates
251 : !!
252 : !! SOURCE
253 :
254 4 : subroutine out_geometry_XML(dtset, level, natom, rprimd, xred)
255 :
256 : !Arguments ------------------------------------
257 : !scalars
258 : integer,intent(in) :: level,natom
259 : type(dataset_type),intent(in) :: dtset
260 : !arrays
261 : real(dp),intent(in) :: rprimd(3,3)
262 : real(dp),intent(inout) :: xred(3,natom)
263 :
264 : !Local variables -------------------------
265 : character(len = 1), parameter :: rprimd_names(3) = (/ "x", "y", "z" /)
266 : !scalars
267 : integer :: i,j
268 : character(len=128) :: spacer,value
269 : !arrays
270 4 : real(dp),allocatable :: xcart(:,:)
271 :
272 : ! *************************************************************************
273 :
274 : !Compute the spacer to put before each markup
275 4 : write(spacer, "(A,I0)") "A", 2 * level
276 4 : write(ab_xml_out, "("//trim(spacer)//",A)") " ", '<geometry>'
277 : !Compute the cartesian coordinates of atoms
278 12 : ABI_MALLOC(xcart,(3, natom))
279 4 : call xred2xcart(natom, rprimd, xcart, xred)
280 : !Ouput the rprimd matrix
281 4 : write(ab_xml_out, "("//trim(spacer)//",A)", advance = "NO") " ", ' <rprimd'
282 16 : do i = 1, 3, 1
283 52 : do j = 1, 3, 1
284 36 : write(value, "(es20.8)") rprimd(i, j)
285 48 : write(ab_xml_out, "(A,A,I0,A,A,A)", advance = "NO") ' ', rprimd_names(i), j, '="', trim(value) ,'"'
286 : end do
287 : end do
288 4 : write(ab_xml_out, "(A)") ' />'
289 : !Output the atom position
290 12 : do i = 1, natom, 1
291 8 : write(ab_xml_out, "("//trim(spacer)//",A)", advance = "NO") " ", ' <position'
292 8 : write(ab_xml_out, "(A,I0,A,I0,A)", advance = "NO") ' atom="a_', dtset%jdtset ,'_', i ,'"'
293 32 : do j = 1, 3, 1
294 24 : write(value, "(es20.8)") xcart(j, i)
295 32 : write(ab_xml_out, "(A,A,A,A,A)", advance = "NO") ' ', rprimd_names(j), '="', trim(value) ,'"'
296 : end do
297 12 : write(ab_xml_out, "(A)") ' />'
298 : end do
299 4 : ABI_FREE(xcart)
300 4 : write(ab_xml_out, "("//trim(spacer)//",A)") " ", '</geometry>'
301 :
302 4 : end subroutine out_geometry_XML
303 : !!***
304 :
305 : end module m_outxml
306 : !!***
|