Line data Source code
1 : !!****m* ABINIT/m_haydock_io
2 : !! NAME
3 : !! m_haydock_io
4 : !!
5 : !! FUNCTION
6 : !! This module provides routines to read the Haydock file used by the
7 : !! Bethe-Salpeter code.
8 : !!
9 : !! COPYRIGHT
10 : !! Copyright (C) 2013-2026 ABINIT group (YG, MG)
11 : !! This file is distributed under the terms of the
12 : !! GNU General Public License, see ~abinit/COPYING
13 : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : !!
15 : !! SOURCE
16 :
17 : #if defined HAVE_CONFIG_H
18 : #include "config.h"
19 : #endif
20 :
21 : #include "abi_common.h"
22 :
23 : MODULE m_haydock_io
24 :
25 : use defs_basis
26 : use m_abicore
27 : use m_errors
28 :
29 : use m_io_tools, only : open_file
30 :
31 : implicit none
32 :
33 : private
34 : !!***
35 :
36 : integer,private,parameter :: CUR_VERSION = 1
37 :
38 : !!****t* m_haydock_io/haydock_type
39 : !! NAME
40 : !! haydock_type
41 : !!
42 : !! FUNCTION
43 : !! The structure defining the content of the haydock file
44 : !!
45 : !! SOURCE
46 :
47 : type,public :: haydock_type
48 :
49 : integer :: version
50 : ! Version of the file
51 :
52 : integer :: hsize
53 : ! Size of the hamiltonian
54 :
55 : integer :: use_coupling
56 : ! 1 if coupling is used, 0 if not
57 :
58 : integer :: op
59 : ! Type of the file
60 :
61 : integer :: nq
62 : ! Number of q-points in the file
63 :
64 : integer :: unt
65 : ! Fortran unit number.
66 :
67 : real(dp) :: broad
68 : ! Broadening factor
69 :
70 : complex(dp) :: factor
71 :
72 : real(dp),allocatable :: qpoints(:,:)
73 : ! qpoints(3,nq)
74 :
75 : integer,allocatable :: niter(:)
76 : ! niter(nq)
77 :
78 : contains
79 :
80 : procedure :: open => open_haydock ! Init the Haydock file
81 : procedure :: read => read_haydock ! Reads the data associated with 1 q-point
82 : procedure :: read_dim => read_dim_haydock ! Read dimensions
83 : procedure :: write_dim => write_dim_haydock ! Write dimensions.
84 : procedure :: skip_dim => skip_dim_haydock ! Skip the section with dimensions.
85 : procedure :: write => write_haydock ! Writes data related to a q-point inside the file
86 : procedure :: close => close_haydock ! Close the Haydock file and release memory
87 : end type haydock_type
88 : !!***
89 :
90 : contains !====================================================================
91 : !!***
92 :
93 : !!****f* m_haydock_io/open_haydock
94 : !! NAME
95 : !! open_haydock
96 : !!
97 : !! FUNCTION
98 : !! Open the file and initialize haydock file descriptor that will
99 : !! be used for later access
100 : !!
101 : !! INPUTS
102 : !! filename = Name of the file to be opened
103 : !!
104 : !! OUTPUT
105 : !! haydock_file = file descriptor for the haydock file
106 : !!
107 : !! SOURCE
108 :
109 18 : subroutine open_haydock(haydock_file, filename)
110 :
111 : !Arguments ------------------------------------
112 : class(haydock_type),intent(out) :: haydock_file
113 : character(len=*),intent(in) :: filename
114 :
115 : !Local variables ------------------------------
116 : character(len=500) :: msg
117 : !************************************************************************
118 :
119 18 : if (open_file(filename,msg,newunit=haydock_file%unt,form="unformatted") /= 0) then
120 0 : ABI_ERROR(msg)
121 : end if
122 :
123 18 : haydock_file%version = CUR_VERSION
124 :
125 18 : end subroutine open_haydock
126 : !!***
127 :
128 : !----------------------------------------------------------------------
129 :
130 : !!****f* m_haydock_io/read_dim_haydock
131 : !! NAME
132 : !! read_dim_haydock
133 : !!
134 : !! FUNCTION
135 : !! Reads the header dimensions of the haydock file and store them in
136 : !! the haydock file descriptor
137 : !!
138 : !! INPUT/OUTPUT
139 : !! haydock_file = haydock file descriptor
140 : !!
141 : !! SOURCE
142 :
143 0 : subroutine read_dim_haydock(haydock_file)
144 :
145 : !Arguments ------------------------------------
146 : class(haydock_type),intent(inout) :: haydock_file
147 :
148 : !Local variables ------------------------------
149 : !scalars
150 : integer :: niter_file
151 : integer :: iq, it
152 : character(len=500) :: msg
153 : !arrays
154 : real(dp) :: q_file(3)
155 : !************************************************************************
156 :
157 0 : read(haydock_file%unt) haydock_file%version
158 :
159 0 : msg = "The haydock file has been produced by an uncompatible version of abinit"
160 0 : ABI_CHECK(haydock_file%version == CUR_VERSION, msg)
161 :
162 0 : read(haydock_file%unt) haydock_file%hsize,haydock_file%use_coupling,&
163 0 : haydock_file%op,haydock_file%nq,haydock_file%broad
164 :
165 0 : ABI_MALLOC(haydock_file%qpoints,(3,haydock_file%nq))
166 0 : ABI_MALLOC(haydock_file%niter,(haydock_file%nq))
167 :
168 0 : do iq = 1,haydock_file%nq
169 0 : read(haydock_file%unt) q_file(:)
170 0 : read(haydock_file%unt) niter_file
171 :
172 0 : haydock_file%qpoints(:,iq) = q_file(:)
173 0 : haydock_file%niter(iq) = niter_file
174 : ! Skip data for this q.
175 0 : do it=1,niter_file
176 0 : read(haydock_file%unt) ! it,aa(it),bb(it)
177 : end do
178 0 : read(haydock_file%unt) ! phi_nm1
179 0 : read(haydock_file%unt) ! phi_n
180 0 : read(haydock_file%unt) ! factor
181 : end do
182 :
183 0 : end subroutine read_dim_haydock
184 : !!***
185 :
186 : !----------------------------------------------------------------------
187 :
188 : !!****f* m_haydock_io/write_dim_haydock
189 : !! NAME
190 : !! write_dim_haydock
191 : !!
192 : !! FUNCTION
193 : !! Writes the basic dimensions stored inside the haydock descriptor inside the file
194 : !!
195 : !! SOURCE
196 :
197 18 : subroutine write_dim_haydock(haydock_file)
198 :
199 : !Arguments ------------------------------------
200 : class(haydock_type),intent(in) :: haydock_file
201 : ! *************************************************************************
202 :
203 18 : write(haydock_file%unt) haydock_file%version
204 18 : write(haydock_file%unt) haydock_file%hsize,haydock_file%use_coupling, &
205 36 : haydock_file%op,haydock_file%nq,haydock_file%broad
206 :
207 18 : end subroutine write_dim_haydock
208 : !!***
209 :
210 : !----------------------------------------------------------------------
211 :
212 : !!****f* m_haydock_io/skip_dim_haydock
213 : !! NAME
214 : !! skip_dim_haydock
215 : !!
216 : !! FUNCTION
217 : !! Skip the part of the file reading basic dimensions contained in the header
218 : !!
219 : !! SOURCE
220 :
221 0 : subroutine skip_dim_haydock(haydock_file)
222 :
223 : !Arguments ------------------------------------
224 : class(haydock_type),intent(in) :: haydock_file
225 : ! *************************************************************************
226 :
227 0 : read(haydock_file%unt)
228 0 : read(haydock_file%unt)
229 :
230 0 : end subroutine skip_dim_haydock
231 : !!***
232 :
233 : !----------------------------------------------------------------------
234 :
235 : !!****f* m_haydock_io/read_haydock
236 : !! NAME
237 : !! read_haydock
238 : !!
239 : !! FUNCTION
240 : !! Reads the data related to one q-point inside the file accessed by file descriptor
241 : !!
242 : !! INPUTS
243 : !! haydock_file = haydock file descriptor
244 : !! q = q-point to be searched inside the file
245 : !!
246 : !! OUTPUT
247 : !! aa = coefficients "a" of the lanczos chain
248 : !! bb = coefficients "b" of the lanczos chain
249 : !! phi_n = last vector of the lanczos chain
250 : !! phi_nm1 = penultimate vector of the lanczos chain
251 : !! niter = number of iterations done
252 : !! factor = pre-factor used to obtain the green function
253 : !!
254 : !! NOTES
255 : !! niter = 0 if the q-point has not been found
256 : !!
257 : !! SOURCE
258 :
259 0 : subroutine read_haydock(haydock_file, q, aa, bb, phi_n, phi_nm1, niter, factor)
260 :
261 : !Arguments ------------------------------------
262 : !scalars
263 : class(haydock_type),intent(in) :: haydock_file
264 : integer,intent(out) :: niter
265 : complex(dp),intent(out) :: factor
266 : !arrays
267 : real(dp),intent(in) :: q(3)
268 : real(dp),allocatable,intent(out) :: bb(:)
269 : complex(dp),allocatable,intent(out) :: aa(:),phi_n(:),phi_nm1(:)
270 :
271 : !Local variables ------------------------------
272 : !scalars
273 : integer :: iq, it, inn, niter_file
274 : logical :: found_q
275 : character(len=500) :: msg
276 : !arrays
277 : real(dp) :: q_file(3)
278 : ! *************************************************************************
279 :
280 0 : rewind(haydock_file%unt)
281 0 : call skip_dim_haydock(haydock_file)
282 :
283 0 : do iq = 1,haydock_file%nq
284 0 : read(haydock_file%unt) q_file(:)
285 0 : read(haydock_file%unt) niter_file
286 :
287 0 : if ( ALL(ABS(q_file - q) < tol6) ) then
288 : found_q = .TRUE.; EXIT
289 : else
290 : ! Skip data for this q.
291 0 : do it=1,niter_file
292 0 : read(haydock_file%unt) ! it,aa(it),bb(it)
293 : end do
294 0 : read(haydock_file%unt) ! phi_nm1
295 0 : read(haydock_file%unt) ! phi_n
296 0 : read(haydock_file%unt) ! factor
297 : end if
298 : end do
299 :
300 : if(found_q) then
301 0 : niter = niter_file
302 0 : ABI_MALLOC(aa,(niter))
303 0 : ABI_MALLOC(bb,(niter))
304 0 : do inn=1,niter
305 0 : read(haydock_file%unt)it,aa(inn),bb(inn)
306 0 : if (inn/=it) then
307 0 : write(msg,'(2(a,i0))')" Found it_file: ",it," while it should be: ",inn
308 0 : ABI_ERROR(msg)
309 : end if
310 : end do
311 0 : ABI_MALLOC(phi_nm1,(haydock_file%hsize))
312 0 : ABI_MALLOC(phi_n,(haydock_file%hsize))
313 0 : read(haydock_file%unt)phi_nm1
314 0 : read(haydock_file%unt)phi_n
315 0 : read(haydock_file%unt)factor
316 : else
317 : niter = 0
318 : end if
319 :
320 0 : end subroutine read_haydock
321 : !!***
322 :
323 : !----------------------------------------------------------------------
324 :
325 : !!****f* m_haydock_io/write_haydock
326 : !! NAME
327 : !! write_haydock
328 : !!
329 : !! FUNCTION
330 : !! Writes data related to a q-point inside the file
331 : !!
332 : !! INPUTS
333 : !! haydock_file = haydock file descriptor
334 : !! q = q-point to be searched inside the file
335 : !! aa = coefficients "a" of the lanczos chain
336 : !! bb = coefficients "b" of the lanczos chain
337 : !! phi_n = last vector of the lanczos chain
338 : !! phi_nm1 = penultimate vector of the lanczos chain
339 : !! niter = number of iterations done
340 : !! factor = pre-factor used to obtain the green function
341 : !!
342 : !! SOURCE
343 :
344 108 : subroutine write_haydock(haydock_file, hsize, q, aa, bb, phi_n, phi_nm1, niter, factor)
345 :
346 : !Arguments ------------------------------------
347 : !scalars
348 : class(haydock_type),intent(in) :: haydock_file
349 : integer,intent(in) :: niter,hsize
350 : complex(dp),intent(in) :: factor
351 : !arrays
352 : real(dp),intent(in) :: q(3)
353 : real(dp),intent(in) :: bb(niter)
354 : complex(dp),intent(in) :: aa(niter),phi_n(hsize),phi_nm1(hsize)
355 :
356 : !Local variables -----------------------------
357 : integer :: it
358 : ! *************************************************************************
359 :
360 108 : write(haydock_file%unt) q
361 108 : write(haydock_file%unt) niter ! NB if the previous loop completed inn=niter_max+1
362 8673 : do it=1,niter ! if we exited then inn is not incremented by one.
363 8673 : write(haydock_file%unt)it,aa(it),bb(it)
364 : end do
365 108 : write(haydock_file%unt) phi_nm1
366 108 : write(haydock_file%unt) phi_n
367 108 : write(haydock_file%unt) factor
368 :
369 108 : end subroutine write_haydock
370 : !!***
371 :
372 : !----------------------------------------------------------------------
373 :
374 : !!****f* m_haydock_io/close_haydock
375 : !! NAME
376 : !! close_haydock
377 : !!
378 : !! FUNCTION
379 : !! Closes the haydock file and free dynamica memory.
380 : !!
381 : !! SOURCE
382 :
383 18 : subroutine close_haydock(haydock_file)
384 :
385 : !Arguments ------------------------------------
386 : class(haydock_type),intent(inout) :: haydock_file
387 : ! *************************************************************************
388 :
389 18 : close(haydock_file%unt)
390 :
391 18 : ABI_SFREE(haydock_file%qpoints)
392 18 : ABI_SFREE(haydock_file%niter)
393 :
394 18 : end subroutine close_haydock
395 : !!***
396 :
397 : !----------------------------------------------------------------------
398 :
399 36 : END MODULE m_haydock_io
400 : !!***
|