Branch data Line data Source code
1 : : !!****m* ABINIT/m_gwls_hamiltonian
2 : : !! NAME
3 : : !! m_gwls_hamiltonian
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2009-2026 ABINIT group (JLJ, BR, MC)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.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 : :
23 : : module m_gwls_hamiltonian
24 : :
25 : : use m_gwls_utility
26 : : use m_gwls_wf
27 : : use m_dtset
28 : : use m_bandfft_kpt
29 : : use m_cgtools
30 : : use defs_basis
31 : : use m_abicore
32 : : use m_xmpi
33 : : use m_pawang
34 : : use m_errors
35 : : use m_abi_mixing
36 : : use m_mpinfo
37 : : use m_crystal
38 : :
39 : : use defs_abitypes, only : MPI_type
40 : : use m_io_tools, only : get_unit
41 : : use m_hamiltonian, only : gs_hamiltonian_type
42 : : use m_pawcprj, only : pawcprj_type
43 : : use m_vcoul, only : vcoul_t
44 : : use m_gsphere, only : gsphere_t
45 : : use m_bz_mesh, only : kmesh_t
46 : : use m_fft, only : fftpac, fourwf
47 : : use m_getghc, only : getghc
48 : : use m_io_kss, only : make_gvec_kss
49 : :
50 : : implicit none
51 : : save
52 : : private
53 : : !!***
54 : :
55 : : !Data passed in argument to build_H and build_vxc that we need to copy for the GW calculation.
56 : : !build_H
57 : : type(dataset_type) :: dtset !Public
58 : : type(MPI_type) :: mpi_enreg !Public
59 : : integer :: cpopt
60 : : real(dp), allocatable :: cg(:,:) !Public
61 : : integer :: dimffnl
62 : : type(gs_hamiltonian_type) :: gs_hamk
63 : : real(dp), allocatable, target :: ffnl(:,:,:,:)
64 : : integer, allocatable, target :: kg_k(:,:)
65 : : real(dp), allocatable, target :: kinpw(:)
66 : : real(dp), allocatable, target :: ph3d(:,:,:)
67 : : real(dp), allocatable, target :: vlocal(:,:,:,:)
68 : : !build_vxc
69 : : real(dp), allocatable :: vxc_dg(:,:)
70 : :
71 : : !Other variables initialized in build_H
72 : : integer :: ndat
73 : : integer :: sij_opt
74 : : integer :: tim_getghc
75 : : integer :: type_calc
76 : : integer :: nfft !Public
77 : : integer :: nline !Public
78 : : integer :: ngfft(18)
79 : : integer :: e !Public
80 : : integer :: nspinor !Public
81 : : integer :: n1, n2, n3
82 : : integer :: n4, n5, n6 !Public
83 : : integer :: npw_k !Public
84 : : integer :: ckpt !Public
85 : : integer :: mgfft
86 : : integer :: tim_fourwf
87 : : integer :: i
88 : : integer :: nband !Public
89 : : integer :: ispden !Public
90 : : integer :: v
91 : : integer :: nbandv !Public
92 : : integer :: mcg
93 : : integer :: ktot !Public
94 : : !integer :: tmp2i(2)
95 : : integer, parameter :: iovar=6 !137 !Public
96 : : integer, allocatable :: gbound(:,:)
97 : : integer, allocatable :: istwfk(:) !Public
98 : : real(dp) :: eshift
99 : : real(dp) :: tolwfr !Public
100 : : real(dp) :: ucvol !Public
101 : : real(dp) :: weight
102 : : real(dp) :: tmpc(2)
103 : : real(dp), allocatable :: vxc(:,:,:,:) !Public (Just the transcript of vxc_dg on the "small" (wfk) real grid)
104 : : real(dp), allocatable :: psik1(:,:) !Working wf in k space for module subtourines.
105 : : real(dp), allocatable :: psik2(:,:) !Working wf in k space for module subtourines.
106 : : real(dp), allocatable :: psik3(:,:) !Working wf in k space for module subtourines. RESERVED FOR Hpsik.
107 : : real(dp), allocatable :: psik4(:,:) !Working wf in k space for module subtourines. RESERVED FOR Hpsik.
108 : : real(dp), allocatable :: psikb1(:,:) !Working wf in k space for module subtourines.
109 : : real(dp), allocatable :: psikb2(:,:) !Working wf in k space for module subtourines.
110 : : real(dp), allocatable :: psikb3(:,:) !Working wf in k space for module subtourines. RESERVED FOR Hpsik.
111 : : real(dp), allocatable :: psikb4(:,:) !Working wf in k space for module subtourines. RESERVED FOR Hpsik.
112 : : real(dp), allocatable :: psig1(:,:) !Working wf in k space for module subtourines.
113 : : real(dp), allocatable :: psig2(:,:) !Working wf in k space for module subtourines.
114 : : real(dp), allocatable :: psig3(:,:) !Working wf in k space for module subtourines. RESERVED FOR Hpsik.
115 : : real(dp), allocatable :: psig4(:,:) !Working wf in k space for module subtourines. RESERVED FOR Hpsik.
116 : : real(dp), allocatable :: psir1(:,:,:,:) !Working wf in real space (sg) for module subtourines.
117 : : real(dp), allocatable :: psir2(:,:,:,:) !Working wf in real space (sg) for module subtourines.
118 : : real(dp), allocatable :: psir3(:,:,:,:) !Working wf in real space (sg) for module subtourines.
119 : : real(dp), allocatable :: psidg(:,:) !Working wf in real space (dg) for module subtourines.
120 : :
121 : : real(dp), allocatable :: denpot(:,:,:) !Working array for real space product of wf with fourwf.
122 : : real(dp), allocatable :: pcon(:)
123 : : real(dp), allocatable :: eig(:) !Public
124 : : real(dp), allocatable :: dummy2(:,:), dummy3(:,:,:)
125 : : real(dp), allocatable :: scprod2(:,:)
126 : : type(pawcprj_type), allocatable :: conjgrprj(:,:) !Not allocated (currently).
127 : :
128 : : !To enable the use of ABINIT GW tools for constructing the square root of the coulomb operator.
129 : : integer :: timrev
130 : : real(dp) :: ecut_eff
131 : : integer, pointer :: gvec(:,:)
132 : : type(vcoul_t) :: Vcp
133 : : type(crystal_t) :: Cryst
134 : : type(gsphere_t) :: Gsphere
135 : : type(kmesh_t) :: Kmesh, Qmesh
136 : : character(len=132),pointer :: title(:) !SET2NULL
137 : : complex(dp), allocatable :: vc_sqrt(:)
138 : :
139 : : !MPI over bands requires :
140 : : integer :: blocksize !Public
141 : : integer :: nbdblock !Public
142 : : integer :: npw_g !Public
143 : : integer :: ikpt_this_proc !Public
144 : : integer :: npw_kb
145 : : integer :: iblock
146 : : integer :: iband
147 : : integer :: n
148 : : integer :: npw_serial
149 : : integer, pointer :: kg_k_gather(:,:)
150 : : real(dp), pointer :: kinpw_gather(:)
151 : : real(dp), pointer :: ph3d_gather(:,:,:)
152 : : real(dp), pointer :: ffnl_gather(:,:,:,:)
153 : : !!***
154 : :
155 : :
156 : : public :: dtset, mpi_enreg, cg, kinpw
157 : : public :: nfft, n4, n5, n6, nline, tolwfr, npw_k, nbandv, eig, nspinor, ckpt
158 : : public :: istwfk, nband, iovar, e, ucvol, vxc, ispden, ktot, kg_k
159 : : public :: Hpsik, Hpsikc, g_to_r, gr_to_g, kbkb_to_kb
160 : : public :: build_H, destroy_H, set_precondition, build_vxc
161 : : public :: unset_precondition, precondition, exchange, dft_xc_energy, sqrt_vc_k, precondition_cplx
162 : : public :: pcon, wf_block_distribute
163 : : public :: blocksize, nbdblock, ikpt_this_proc, npw_g, npw_kb, kg_k_gather, kinpw_gather
164 : :
165 : : public :: dummy2, dummy3, mgfft, ngfft, weight, gbound, psir1, psir3, tim_fourwf
166 : :
167 : : real(dp), public, allocatable :: kernel_wavefunctions_FFT(:,:,:)
168 : : real(dp), public, allocatable :: valence_wavefunctions_FFT(:,:,:)
169 : :
170 : : public :: pc_k_valence_kernel
171 : : ! public :: CleanupSQMRKernel
172 : : !!***
173 : :
174 : : contains
175 : :
176 : :
177 : : !!****f* m_gwls_hamiltonian/DistributeValenceWavefunctions
178 : : !! NAME
179 : : !! DistributeValenceWavefunctions
180 : : !!
181 : : !! FUNCTION
182 : : !! .
183 : : !!
184 : : !! INPUTS
185 : : !!
186 : : !! OUTPUT
187 : : !!
188 : : !! SOURCE
189 : :
190 : 8 : subroutine DistributeValenceWavefunctions()
191 : : !--------------------------------------------------------------------------------
192 : : !
193 : : ! This subroutine distributes, once and for all, the valence wavefunctions to
194 : : ! the FFT configuration. They will thus be ready to be used within the
195 : : ! susceptibility operator.
196 : : !
197 : : !--------------------------------------------------------------------------------
198 : : integer :: iblk, mb, v
199 : :
200 : 8 : real(dp), allocatable :: psik_v(:,:) !wavefunctions in LA format
201 : 8 : real(dp), allocatable :: psik_v_alltoall(:,:) !wavefunctions in FFT format
202 : :
203 : : ! *************************************************************************
204 : :
205 : :
206 : :
207 : : !===================================================================
208 : : ! Allocate the global array which will contain the valence states
209 : : !===================================================================
210 [ - + + - : 32 : ABI_MALLOC( valence_wavefunctions_FFT, (2,npw_g,nbdblock))
- + + - +
- + - - +
- + - + ]
211 : :
212 [ + + + + : 38618 : valence_wavefunctions_FFT = zero
+ + ]
213 : :
214 : :
215 : : !====================================================
216 : : ! Allocate working arrays
217 : : !====================================================
218 : :
219 [ - + + - : 24 : ABI_MALLOC(psik_v, (2,npw_kb))
+ - + - -
+ - + ]
220 [ - + + - : 24 : ABI_MALLOC(psik_v_alltoall,(2,npw_g))
+ - + - -
+ + - ]
221 : :
222 : :
223 : :
224 : : ! loop on all blocks of states,
225 [ + + ]: 68 : do iblk = 1, nbdblock
226 : :
227 : : ! loop on valence states for this block; if the state is conduction, fill with zeros
228 [ + + ]: 140 : do mb = 1, blocksize
229 : :
230 : 80 : v = (iblk-1)*blocksize+mb
231 : :
232 [ + + ]: 140 : if (v <= nbandv) then
233 [ + + + + ]: 15452 : psik_v(:,(mb-1)*npw_k+1:mb*npw_k) = cg(:,(v-1)*npw_k+1:v*npw_k)
234 : : else
235 [ + + + + ]: 23178 : psik_v(:,(mb-1)*npw_k+1:mb*npw_k) = zero
236 : : end if
237 : :
238 : : end do
239 : :
240 : : ! change configuration of the data
241 : 60 : call wf_block_distribute(psik_v, psik_v_alltoall,1) ! LA -> FFT
242 : :
243 : : ! copy data in global array
244 : :
245 [ + + + + ]: 38618 : valence_wavefunctions_FFT(:,:,iblk) = psik_v_alltoall(:,:)
246 : :
247 : : end do
248 : :
249 : : !====================================================
250 : : ! cleanup
251 : : !====================================================
252 : :
253 [ - + ]: 8 : ABI_FREE(psik_v)
254 [ - + ]: 8 : ABI_FREE(psik_v_alltoall)
255 : :
256 : :
257 : 8 : end subroutine DistributeValenceWavefunctions
258 : : !!***
259 : :
260 : : !!****f* m_gwls_hamiltonian/DistributeValenceKernel
261 : : !! NAME
262 : : !! DistributeValenceKernel
263 : : !!
264 : : !! FUNCTION
265 : : !! .
266 : : !!
267 : : !! INPUTS
268 : : !!
269 : : !! OUTPUT
270 : : !!
271 : : !! SOURCE
272 : :
273 : 8 : subroutine DistributeValenceKernel()
274 : : !--------------------------------------------------------------------------------
275 : : !
276 : : ! This subroutine distributes, once and for all, the kernel of the static
277 : : ! SQMR operator.
278 : : !
279 : : ! In this first, quick and dirty implementation, we simply distribute
280 : : ! ALL the valence bands on ALL the FFT groups. This is not efficient, but
281 : : ! kernel projections are not a bottleneck of the computation.
282 : : !
283 : : ! A better (forthcoming) algorithm would only distribute the actual kernel,
284 : : ! not all valence bands.
285 : : !--------------------------------------------------------------------------------
286 : :
287 : : integer :: mb, n
288 : :
289 : 8 : real(dp), allocatable :: psik_n(:,:) !wavefunctions in LA format
290 : 8 : real(dp), allocatable :: psik_n_alltoall(:,:) !wavefunctions in FFT format
291 : :
292 : : ! *************************************************************************
293 : :
294 : :
295 : : !===================================================================
296 : : ! Allocate the global array which will contain the valence states
297 : : !===================================================================
298 [ - + + - : 32 : ABI_MALLOC( kernel_wavefunctions_FFT, (2,npw_g, nband))
- + + - +
- + - - +
- + - + ]
299 : :
300 [ + + + + : 46348 : kernel_wavefunctions_FFT = zero
+ + ]
301 : :
302 : : !====================================================
303 : : ! Allocate working arrays
304 : : !====================================================
305 : :
306 [ - + + - : 24 : ABI_MALLOC(psik_n, (2,npw_kb))
+ - + - -
+ - + ]
307 [ - + + - : 24 : ABI_MALLOC(psik_n_alltoall,(2,npw_g))
+ - + - -
+ + - ]
308 : :
309 : :
310 : : ! loop on all valence states
311 [ + + ]: 88 : do n = 1, nband
312 : :
313 : : ! Copy multiple instances of this valence state in the array;
314 : : ! this way, each FFT group will have ALL the valence states!
315 [ + + ]: 200 : do mb = 1, blocksize
316 [ + + + + ]: 46460 : psik_n(:,(mb-1)*npw_k+1:mb*npw_k) = cg(:,(n-1)*npw_k+1:n*npw_k)
317 : : end do
318 : :
319 : : ! change configuration of the data
320 : 80 : call wf_block_distribute(psik_n, psik_n_alltoall,1) ! LA -> FFT
321 : :
322 : : ! copy data in global array
323 [ + + + + ]: 46348 : kernel_wavefunctions_FFT(:,:,n) = psik_n_alltoall(:,:)
324 : :
325 : : end do
326 : :
327 : : !====================================================
328 : : ! cleanup
329 : : !====================================================
330 : :
331 [ - + ]: 8 : ABI_FREE(psik_n)
332 [ - + ]: 8 : ABI_FREE(psik_n_alltoall)
333 : :
334 : 8 : end subroutine DistributeValenceKernel
335 : : !!***
336 : :
337 : : !!****f* m_gwls_hamiltonian/pc_k_valence_kernel
338 : : !! NAME
339 : : !! pc_k_valence_kernel
340 : : !!
341 : : !! FUNCTION
342 : : !! .
343 : : !!
344 : : !! INPUTS
345 : : !!
346 : : !! OUTPUT
347 : : !!
348 : : !! SOURCE
349 : :
350 : 38570 : subroutine pc_k_valence_kernel(psi_inout,n)
351 : :
352 : : !================================================================================
353 : : ! This routine projects out of the valence kernel. It assumes the input/output
354 : : ! array is distributed in the FFT configuration, and that the global
355 : : ! array containing the kernel (defined in this module) is already prepared
356 : : ! and ready to be used.
357 : : !================================================================================
358 : :
359 : : real(dp), intent(inout) :: psi_inout(2,npw_g)
360 : : integer , intent(in), optional :: n
361 : :
362 : :
363 : 38570 : real(dp), allocatable :: psi_projected(:,:)
364 : :
365 : : real(dp) :: tmpc(2)
366 : :
367 : : integer :: v, n_max
368 : :
369 : : integer :: mpi_communicator, ierr
370 : :
371 : : ! *************************************************************************
372 : :
373 : :
374 [ - + + - : 115710 : ABI_MALLOC( psi_projected, (2,npw_g))
+ - + - -
+ - + ]
375 : :
376 : 38570 : mpi_communicator = mpi_enreg%comm_fft
377 : :
378 [ - + ]: 38570 : if (present(n)) then
379 : 0 : n_max = n
380 : : else
381 : 38570 : n_max = nbandv
382 : : end if
383 : :
384 : : !====================================================
385 : : ! Compute projection
386 : : !====================================================
387 : :
388 [ + + + + ]: 23370572 : psi_projected(:,:) = zero
389 : :
390 [ + + ]: 192850 : do v = 1, n_max
391 : :
392 : : ! compute overlap of kernel member with function
393 : 154280 : tmpc = cg_zdotc(npw_g ,kernel_wavefunctions_FFT(:,:,v),psi_inout(:,:))
394 : :
395 : : ! Communicate results
396 : 154280 : call xmpi_sum(tmpc, mpi_communicator, ierr) ! sum on all processors working on FFT!
397 : :
398 : : ! add overlap with array to project
399 [ + + ]: 31263616 : psi_projected(1,:) = psi_projected(1,:) + (tmpc(1)*kernel_wavefunctions_FFT(1,:,v)-tmpc(2)*kernel_wavefunctions_FFT(2,:,v))
400 [ + + ]: 31302186 : psi_projected(2,:) = psi_projected(2,:) + (tmpc(1)*kernel_wavefunctions_FFT(2,:,v)+tmpc(2)*kernel_wavefunctions_FFT(1,:,v))
401 : :
402 : : !psi_inout(1,:) = psi_inout(1,:) -( tmpc(1)*kernel_wavefunctions_FFT(1,:,v)-tmpc(2)*kernel_wavefunctions_FFT(2,:,v) )
403 : : !psi_inout(2,:) = psi_inout(2,:) -( tmpc(1)*kernel_wavefunctions_FFT(2,:,v)+tmpc(2)*kernel_wavefunctions_FFT(1,:,v) )
404 : :
405 : :
406 : : end do
407 : :
408 [ + - ]: 38570 : if (present(n)) then
409 [ # # # # ]: 0 : psi_inout(:,:) = psi_projected(:,:)
410 : : else
411 [ + + + + ]: 23370572 : psi_inout(:,:) = psi_inout(:,:) - psi_projected(:,:)
412 : : end if
413 : :
414 : :
415 : :
416 [ - + ]: 38570 : ABI_FREE( psi_projected)
417 : :
418 : 38570 : end subroutine pc_k_valence_kernel
419 : : !!***
420 : :
421 : : !!****f* m_gwls_hamiltonian/wf_block_distribute
422 : : !! NAME
423 : : !! wf_block_distribute
424 : : !!
425 : : !! FUNCTION
426 : : !! .
427 : : !!
428 : : !! INPUTS
429 : : !!
430 : : !! OUTPUT
431 : : !!
432 : : !! SOURCE
433 : :
434 : 6722 : subroutine wf_block_distribute(psik, psik_alltoall, direction)
435 : :
436 : : !================================================================================
437 : : !
438 : : ! This subroutine distributes a block of wavefunctions in the "linear algebra"
439 : : ! configuration, to a configuration appropriate to perform FFT (or apply Hamiltonian).
440 : : !
441 : : ! The code below is inspired by the subroutine prep_getghc, which rearranges
442 : : ! data over MPI processors prior to applying the Hamiltonian.
443 : : !
444 : : ! input:
445 : : ! npw_kb : dimension of wavefunctions in the "linear algebra" configuration,
446 : : ! which means the G-vectors are distributed over all
447 : : ! processors, and every processor has information about all the bands.
448 : : !
449 : : !
450 : : ! npw_g : dimension of wavefunctions in the "FFT" configuration,
451 : : ! which means the G-vectors are distributed along rows of the
452 : : ! MPI topology, and a given row only has one band.
453 : : !
454 : : ! direction : Are we going from LA to FFT, or from FFT to LA?
455 : : ! 1 : LA -> FFT
456 : : ! 2 : LA <- FFT
457 : : !
458 : : ! input/output:
459 : : ! psik : block of wavefunctions, in LA configuration
460 : : ! psik_alltoall : wavefunction, in FFT configuration
461 : : !================================================================================
462 : :
463 : : integer , intent(in) :: direction ! flag which determines the direction of the transfer
464 : : real(dp), intent(inout) :: psik(2,npw_kb) ! block of wavefunctions, in "linear algebra" configuration
465 : : real(dp), intent(inout) :: psik_alltoall(2,npw_g) ! wavefunction in "FFT" configuration; a single band, but more G-vectors
466 : :
467 : :
468 : : integer :: ier, spaceComm
469 : :
470 : 6722 : integer,allocatable :: rdisplsloc(:)
471 : 6722 : integer,allocatable :: recvcountsloc(:)
472 : 6722 : integer,allocatable :: sdisplsloc(:)
473 : 6722 : integer,allocatable :: sendcountsloc(:)
474 : :
475 : : integer :: nproc_band, bandpp
476 : :
477 : 6722 : integer,pointer :: rdispls(:)
478 : 6722 : integer,pointer :: recvcounts(:)
479 : 6722 : integer,pointer :: sdispls(:)
480 : 6722 : integer,pointer :: sendcounts(:)
481 : :
482 : : ! *************************************************************************
483 : :
484 : :
485 : : ! extract information in order to perform MPI communication.
486 : : ! This code comes from prep_getghc
487 : 6722 : nproc_band = mpi_enreg%nproc_band
488 : 6722 : bandpp = mpi_enreg%bandpp
489 : :
490 : 6722 : if(mpi_enreg%nproc_band*mpi_enreg%bandpp > 1) then
491 : :
492 : 2664 : spaceComm=mpi_enreg%comm_fft
493 [ + - ]: 2664 : if(mpi_enreg%paral_kgb==1) spaceComm=mpi_enreg%comm_band
494 : :
495 [ - + + - : 7992 : ABI_MALLOC(sendcountsloc,(nproc_band))
+ - + - -
+ - + ]
496 [ - + + - : 5328 : ABI_MALLOC(sdisplsloc ,(nproc_band))
- + - + ]
497 [ - + + - : 5328 : ABI_MALLOC(recvcountsloc,(nproc_band))
- + - + ]
498 [ - + + - : 5328 : ABI_MALLOC(rdisplsloc ,(nproc_band))
- + - + ]
499 : :
500 : 2664 : recvcounts =>bandfft_kpt(ikpt_this_proc)%recvcounts(:)
501 : 2664 : sendcounts =>bandfft_kpt(ikpt_this_proc)%sendcounts(:)
502 : 2664 : rdispls =>bandfft_kpt(ikpt_this_proc)%rdispls (:)
503 : 2664 : sdispls =>bandfft_kpt(ikpt_this_proc)%sdispls (:)
504 : :
505 [ + + ]: 7992 : recvcountsloc(:)= recvcounts(:)*2*nspinor*bandpp
506 [ + + ]: 7992 : rdisplsloc(:) = rdispls(:)*2*nspinor*bandpp
507 [ + + ]: 7992 : sendcountsloc(:)= sendcounts(:)*2*nspinor
508 [ + + ]: 7992 : sdisplsloc(:) = sdispls(:)*2*nspinor
509 : :
510 : : ! use MPI to communicate information!
511 [ + + ]: 2664 : if (direction == 1) then
512 : : ! LA -> FFT
513 : 652 : call xmpi_alltoallv(psik, sendcountsloc, sdisplsloc, psik_alltoall, recvcountsloc,rdisplsloc, spaceComm, ier)
514 : :
515 [ + - ]: 2012 : else if (direction == 2) then
516 : : ! FFT -> LA
517 : :
518 : 2012 : call xmpi_alltoallv(psik_alltoall,recvcountsloc,rdisplsloc, psik, sendcountsloc,sdisplsloc,spaceComm,ier)
519 : :
520 : : end if
521 : :
522 [ - + ]: 2664 : ABI_FREE(sendcountsloc)
523 [ - + ]: 2664 : ABI_FREE(sdisplsloc )
524 [ - + ]: 2664 : ABI_FREE(recvcountsloc)
525 [ - + ]: 2664 : ABI_FREE(rdisplsloc )
526 : :
527 : : else
528 : :
529 [ + + + + : 674926 : if(direction == 1) psik_alltoall = psik
+ + ]
530 : :
531 [ + + + + : 2465966 : if(direction == 2) psik = psik_alltoall
+ + ]
532 : :
533 : : end if
534 : :
535 [ + + - + : 13444 : end subroutine wf_block_distribute
- + - + -
+ ]
536 : : !!***
537 : :
538 : :
539 : :
540 : : !!****f* m_gwls_hamiltonian/exchange
541 : : !! NAME
542 : : !! exchange
543 : : !!
544 : : !! FUNCTION
545 : : !! .
546 : : !!
547 : : !! INPUTS
548 : : !!
549 : : !! OUTPUT
550 : : !!
551 : : !!
552 : : !!
553 : : !! SOURCE
554 : :
555 [ + + + - : 9 : function exchange(e, Lbasis_lanczos)
- + ]
556 : :
557 : : !use m_bandfft_kpt
558 : : use m_cgtools
559 : : !================================================================================
560 : : ! This subroutine computes the exchange energy in band+FFT parallel
561 : : !
562 : : !================================================================================
563 : : real(dp) :: exchange
564 : :
565 : : integer, intent(in) :: e
566 : :
567 : : ! If these arguments are provided, the exchange energy is to be projected on this subspace
568 : : complex(dp), optional, intent(in) :: Lbasis_lanczos(:,:) ! complex array which contains the Lanczos basis
569 : :
570 : 9 : real(dp), allocatable :: psik_e(:,:) !Working array to store the wavefunction
571 : :
572 : 9 : real(dp), allocatable :: psik_v(:,:) !Working array to store the wavefunction
573 : :
574 : 9 : real(dp), allocatable :: psik_out(:,:) !Working array to store the wavefunction
575 : :
576 : :
577 : : integer :: iblk, mb
578 : :
579 : : integer :: l, lmax
580 : :
581 : : real(dp) :: tmpc(2)
582 : :
583 : : logical :: project
584 : :
585 : : ! *************************************************************************
586 : :
587 : : !--------------------------------------------------------------------------------
588 : : ! Determine if the exhcange energy must be projected on the Lanczos basis
589 : : ! a truncated Coulomb potential
590 : : !--------------------------------------------------------------------------------
591 : :
592 : 9 : project = .false.
593 [ + + ]: 9 : if (present(Lbasis_lanczos)) then
594 : 1 : project = .true.
595 : 1 : lmax = size(Lbasis_lanczos, 2)
596 : : end if
597 : :
598 : : !--------------------------------------------------------------------------------
599 : : ! The goal of this routine is to compute the exchange energy using
600 : : ! a truncated Coulomb potential
601 : : !--------------------------------------------------------------------------------
602 : :
603 : 9 : exchange = 0.0_dp
604 : :
605 : : !====================================================
606 : : ! build the block of wavefunctions which will
607 : : ! contain copies the e-state
608 : : !====================================================
609 : :
610 [ - + + - : 27 : ABI_MALLOC(psik_e,(2,npw_kb))
+ - + - -
+ - + ]
611 : :
612 : : ! fill psik_e with as many copies of the e-state as there are band processors;
613 : : ! that way, upon LA -> FFT, each row of fft processors will have the e-state
614 [ + + ]: 22 : do v = 1, blocksize
615 [ + + + + ]: 5419 : psik_e(:,(v-1)*npw_k+1:v*npw_k) = cg(:,(e-1)*npw_k+1:e*npw_k)
616 : : end do
617 : :
618 : : !====================================================
619 : : ! Allocate the block of wavefunctions which will
620 : : ! contain the valence states
621 : : !====================================================
622 : :
623 [ - + + - : 18 : ABI_MALLOC(psik_v, (2,npw_kb))
- + - + ]
624 [ - + + - : 18 : ABI_MALLOC(psik_out, (2,npw_kb))
- + - + ]
625 : :
626 : : ! loop on all blocks of states,
627 [ + + ]: 79 : do iblk = 1, nbdblock
628 : :
629 : : ! loop on valence states for this block; if the state is conduction, fill with zeros
630 [ + + ]: 160 : do mb = 1, blocksize
631 : :
632 : 90 : v = (iblk-1)*blocksize+mb
633 : :
634 [ + + ]: 160 : if (v <= nbandv) then
635 [ + + + + ]: 18540 : psik_v(:,(mb-1)*npw_k+1:mb*npw_k) = cg(:,(v-1)*npw_k+1:v*npw_k)
636 : : else
637 [ + + + + ]: 27810 : psik_v(:,(mb-1)*npw_k+1:mb*npw_k) = zero
638 : : end if
639 : :
640 : : end do
641 : :
642 : 70 : call kbkb_to_kb(psik_out,psik_v,psik_e)
643 : :
644 : : ! apply Coulomb potential, and take norm: cumulate the exchange energy
645 [ + + ]: 169 : do mb = 1, blocksize
646 : :
647 [ + - + - : 46440 : psik1 = psik_out(:,(mb-1)*npw_k+1:mb*npw_k)
- + - - +
+ + + ]
648 : 90 : call sqrt_vc_k(psik1)
649 : :
650 [ + + ]: 160 : if (project) then
651 : : ! project on the Lanczos basis
652 [ + + ]: 90 : do l = 1, lmax
653 [ + + ]: 20640 : psik2(1,:) = dble(Lbasis_lanczos(:,l))
654 [ + + ]: 20640 : psik2(2,:) = dimag(Lbasis_lanczos(:,l))
655 : 80 : tmpc = scprod_k(psik2,psik1)
656 : 90 : exchange = exchange - (tmpc(1)**2+tmpc(2)**2)
657 : : end do
658 : : else
659 : : ! compute the "exact" exchange energy
660 : 80 : exchange = exchange - norm_k(psik1)**2
661 : : end if
662 : :
663 : : end do
664 : :
665 : : end do
666 : :
667 [ - + ]: 9 : ABI_FREE(psik_e)
668 : :
669 [ - + ]: 9 : ABI_FREE(psik_v)
670 : :
671 [ - + ]: 9 : ABI_FREE(psik_out)
672 : :
673 : 9 : end function exchange
674 : : !!***
675 : :
676 : :
677 : : !!****f* m_gwls_hamiltonian/dft_xc_energy
678 : : !! NAME
679 : : !! dft_xc_energy
680 : : !!
681 : : !! FUNCTION
682 : : !! .
683 : : !!
684 : : !! INPUTS
685 : : !!
686 : : !! OUTPUT
687 : : !!
688 : : !!
689 : : !!
690 : : !! SOURCE
691 : :
692 : 8 : function dft_xc_energy(e)
693 : :
694 : : real(dp) :: dft_xc_energy
695 : : integer, intent(in) :: e
696 : :
697 : :
698 : : integer :: cplex, option, ierr
699 : 8 : real(dp), allocatable :: psik_e(:,:) !Working array to store the wavefunction
700 : 8 : real(dp), allocatable :: psik_e_alltoall(:,:) !Working array to store the wavefunction
701 : :
702 : 8 : real(dp), allocatable :: psik_out(:,:) !Working array to store the wavefunction
703 : :
704 : : real(dp) :: tmpc(2)
705 : : integer :: mpi_communicator
706 : : real(dp) :: dft_xc_energy_tmp
707 : :
708 : : ! *************************************************************************
709 : :
710 : : !--------------------------------------------------------------------------------
711 : : ! The goal of this routine is to compute the xc energy using
712 : : ! the DFT Vxc array.
713 : : !--------------------------------------------------------------------------------
714 : :
715 : : ! Parallel-MPI code. This is inspired from code within the getghc routine, which
716 : : ! applies a complex potential to a wavefunction.
717 : :
718 : :
719 : 8 : cplex = 1 ! real potential
720 : 8 : option = 2 ! multiply wavefunction by potential
721 : 8 : nspinor= 1
722 : : ! Allocate wavefunction arrays which contains the coefficients of the e-state
723 [ - + + - : 24 : ABI_MALLOC(psik_e, (2,npw_kb))
+ - + - -
+ - + ]
724 [ - + + - : 24 : ABI_MALLOC(psik_e_alltoall,(2,npw_g))
+ - + - -
+ - + ]
725 [ - + + - : 24 : ABI_MALLOC(psik_out, (3,npw_g))
+ - + - -
+ + - ]
726 : :
727 : :
728 : : ! Only fetch the e-state, setting other states in block to zero!
729 [ + + + + ]: 4634 : psik_e(:,:) = zero
730 [ + + + + ]: 3863 : psik_e(:,1:npw_k) = cg(:,(e-1)*npw_k+1:e*npw_k)
731 [ + + + + ]: 6176 : psik_out(:,:) = zero
732 : :
733 : :
734 : : ! change the configuration of the data
735 : 8 : call wf_block_distribute(psik_e, psik_e_alltoall,1) ! LA -> FFT
736 : :
737 : :
738 : : ! Call fourwf to generate the product, in k-space
739 : : ! Computation:
740 : : ! psik_e_alltoall(k) -> psi(r)
741 : : ! res(r) = (vxc(r) x psi(r))
742 : : ! psik_out(k) <- res(r)
743 : : ! psir3 is a dummy, not used here.
744 : :
745 : : call fourwf(cplex,vxc(:,:,:,ispden),psik_e_alltoall,psik_out,psir3,gbound,gbound,istwfk(ckpt),kg_k_gather,kg_k_gather,mgfft,&
746 [ - + - + ]: 8 : & mpi_enreg,1,ngfft,npw_g,npw_g,n4,n5,n6,option,tim_fourwf,weight,weight)
747 : :
748 : :
749 : 8 : tmpc = cg_zdotc(npw_g, psik_e_alltoall,psik_out)
750 : :
751 : 8 : mpi_communicator = mpi_enreg%comm_fft
752 : 8 : call xmpi_sum(tmpc,mpi_communicator, ierr) ! sum on all processors working on FFT!
753 : :
754 : 8 : dft_xc_energy_tmp = tmpc(1)
755 : :
756 : 8 : mpi_communicator = mpi_enreg%comm_band
757 : 8 : call xmpi_sum(dft_xc_energy_tmp,mpi_communicator, ierr) ! sum on all processors working on FFT!
758 : :
759 : 8 : dft_xc_energy = dft_xc_energy_tmp
760 : :
761 [ - + ]: 8 : ABI_FREE(psik_e)
762 [ - + ]: 8 : ABI_FREE(psik_e_alltoall)
763 [ - + ]: 8 : ABI_FREE(psik_out)
764 : :
765 : 8 : end function dft_xc_energy
766 : : !!***
767 : :
768 : : !!****f* m_gwls_hamiltonian/set_precondition
769 : : !! NAME
770 : : !! set_precondition
771 : : !!
772 : : !! FUNCTION
773 : : !! .
774 : : !!
775 : : !! INPUTS
776 : : !!
777 : : !! OUTPUT
778 : : !!
779 : : !! SOURCE
780 : :
781 : 736 : subroutine set_precondition(lambda,omega)
782 : : !--------------------------------------------------------------------------------
783 : : ! This subroutine preconditions the problem
784 : : !
785 : : ! A x = b,
786 : : !
787 : : ! with:
788 : : !
789 : : ! omega lambda Operator
790 : : ! ------------------------------------------------------
791 : : ! absent absent A = (H - lambda_0) (value of lambda_0 not important)
792 : : ! present present A = (H - lambda)^2 + omega^2
793 : : ! other cases not implemented
794 : : !
795 : : !
796 : : ! In the above, b = psik.
797 : : !
798 : : !--------------------------------------------------------------------------------
799 : :
800 : : ! TODO :
801 : : ! - eliminate the 2 "if(kinpw(i) < huge(zero)*1.0d-11)"
802 : : ! since ecutsm = 0.0 always (check if that's true in this gw_sternheimer subroutine).
803 : :
804 : : real(dp), intent(in), optional :: lambda, omega
805 : :
806 : : real(dp) :: poly, x
807 : : logical :: omega_imaginary
808 : :
809 : :
810 : : !integer,save :: counter = 0
811 : : !integer :: io_unit
812 : : !character(18):: filename
813 : : !logical :: file_exists
814 : :
815 : : ! *************************************************************************
816 : :
817 : :
818 [ + - ]: 736 : if (present(lambda) .and. present(omega)) then
819 : : omega_imaginary =.true.
820 : : else
821 : 736 : omega_imaginary =.false.
822 : : end if
823 : :
824 : : !io_unit = get_unit()
825 : : !filename = "PRECONDITIONER.log"
826 : : !inquire(file=filename,exist=file_exists)
827 : :
828 : : !if (file_exists) then
829 : : ! open(io_unit,file=filename,position='append',status=files_status_old)
830 : : !else
831 : : ! open(io_unit,file=filename,status=files_status_new)
832 : : ! write(io_unit,10) "#======================================================================================="
833 : : ! write(io_unit,10) "# "
834 : : ! write(io_unit,10) "# This file contains information regarding the preconditioning scheme for SQMR. "
835 : : ! write(io_unit,10) "# "
836 : : ! write(io_unit,10) "#======================================================================================="
837 : : !end if
838 : :
839 : : !counter = counter + 1
840 : : !write(io_unit,10) "# "
841 : : !write(io_unit,15) "# Call #:", counter
842 : : !if (present(lambda) .and. present(omega)) then
843 : : ! write(io_unit,10) "# lambda and omega are present: imaginary frequency case"
844 : : !else
845 : : ! write(io_unit,10) "# lambda and omega are absent: omega = 0 case"
846 : : !end if
847 : :
848 : : !do i=1,npw_k
849 : :
850 [ + + ]: 148768 : do i = 1, npw_g
851 : :
852 [ - + ]: 148032 : if(omega_imaginary) then
853 : 0 : x = (kinpw_gather(i)-lambda)**2 + omega**2
854 : : else
855 : 148032 : x = kinpw_gather(i)
856 : : end if
857 : :
858 [ + - ]: 148768 : if(x < huge(zero)*1.0d-11) then
859 : 148032 : poly = 27.0 + x*(18.0 + x*(12.0 + 8.0*x))
860 : 148032 : pcon(i) = poly/(poly + 16.0*(x**4))
861 : : !pcon(i) = 1.0/(1.0+x) !I don't know why, it gives better results for Silane than the above polynomial.
862 : : else
863 : 0 : pcon(i) = zero
864 : : end if
865 : : end do
866 : :
867 : : !write(io_unit,30) " prec( 1: 10) = ",pcon(1:10)
868 : : !write(io_unit,30) " prec(npw_k-10:npw_k) = ",pcon(npw_k-10:npw_k)
869 : :
870 : : !close(io_unit)
871 : :
872 : : !10 format(A)
873 : : !15 format(A,I8)
874 : : !30 format(A,1000(ES24.12))
875 : :
876 : 736 : end subroutine set_precondition
877 : : !!***
878 : :
879 : : !!****f* m_gwls_hamiltonian/unset_precondition
880 : : !! NAME
881 : : !! unset_precondition
882 : : !!
883 : : !! FUNCTION
884 : : !! .
885 : : !!
886 : : !! INPUTS
887 : : !!
888 : : !! OUTPUT
889 : : !!
890 : : !! SOURCE
891 : :
892 : 128 : subroutine unset_precondition()
893 : :
894 : : ! *************************************************************************
895 : :
896 [ + + ]: 33024 : pcon = one
897 : 128 : end subroutine unset_precondition
898 : : !!***
899 : :
900 : : !!****f* m_gwls_hamiltonian/precondition
901 : : !! NAME
902 : : !! precondition
903 : : !!
904 : : !! FUNCTION
905 : : !! .
906 : : !!
907 : : !! INPUTS
908 : : !!
909 : : !! OUTPUT
910 : : !!
911 : : !! SOURCE
912 : :
913 : 16285 : subroutine precondition(psi_out,psi_in)
914 : :
915 : : real(dp), intent(out) :: psi_out(2,npw_g)
916 : : real(dp), intent(in) :: psi_in(2,npw_g)
917 : :
918 : : ! *************************************************************************
919 : :
920 [ + + ]: 3274274 : do i=1,npw_g
921 [ + + ]: 9790252 : psi_out(:,i) = psi_in(:,i)*pcon(i)
922 : : end do
923 : :
924 : 16285 : end subroutine precondition
925 : : !!***
926 : :
927 : : !!****f* m_gwls_hamiltonian/precondition_cplx
928 : : !! NAME
929 : : !! precondition_cplx
930 : : !!
931 : : !! FUNCTION
932 : : !! .
933 : : !!
934 : : !! INPUTS
935 : : !!
936 : : !! OUTPUT
937 : : !!
938 : : !! SOURCE
939 : :
940 : 7352 : subroutine precondition_cplx(psi_out,psi_in)
941 : :
942 : : complex(dp), intent(out) :: psi_out(npw_g)
943 : : complex(dp), intent(in) :: psi_in(npw_g)
944 : :
945 : : ! *************************************************************************
946 : :
947 [ + + ]: 1896816 : do i=1,npw_g
948 : 1896816 : psi_out(i) = psi_in(i)*pcon(i)
949 : : end do
950 : 7352 : end subroutine precondition_cplx
951 : : !!***
952 : :
953 : : !!****f* m_gwls_hamiltonian/sqrt_vc_k
954 : : !! NAME
955 : : !! sqrt_vc_k
956 : : !!
957 : : !! FUNCTION
958 : : !! .
959 : : !!
960 : : !! INPUTS
961 : : !!
962 : : !! OUTPUT
963 : : !!
964 : : !! SOURCE
965 : :
966 : 1165 : subroutine sqrt_vc_k(psi_inout)
967 : :
968 : : !External variables
969 : : real(dp), intent(inout) :: psi_inout(2,npw_k)
970 : :
971 : : !Internal variable
972 : : complex(dp) :: c
973 : :
974 : : ! *************************************************************************
975 : :
976 [ + + ]: 177210 : do i=1,npw_k
977 : 176045 : c = vc_sqrt(i) * cmplx(psi_inout(1,i),psi_inout(2,i),dp)
978 : 176045 : psi_inout(1,i) = dble (c)
979 : 177210 : psi_inout(2,i) = dimag(c)
980 : : end do
981 : 1165 : end subroutine sqrt_vc_k
982 : : !!***
983 : :
984 : : !!****f* m_gwls_hamiltonian/Hpsik
985 : : !! NAME
986 : : !! Hpsik
987 : : !!
988 : : !! FUNCTION
989 : : !! .
990 : : !!
991 : : !! INPUTS
992 : : !!
993 : : !! OUTPUT
994 : : !!
995 : : !! SOURCE
996 : :
997 : 17569 : subroutine Hpsik(psi_out,psi_in,cte)
998 : :
999 : : !External variables
1000 : : real(dp), intent(inout) :: psi_out(2,npw_g)
1001 : : real(dp), intent(inout), optional :: psi_in(2,npw_g)
1002 : : real(dp), intent(in), optional :: cte
1003 : :
1004 : : ! *************************************************************************
1005 : :
1006 : : !psikb1 is allocated in init_hamiltonian and destroyed in destroy_hamiltonian, to avoid doing it at each application of
1007 : : !the hamiltonian...
1008 : :
1009 : : !We are keeping track of how the module treat each argument of the hamiltonian (subroutine getghc) here.
1010 : : !Legend : T = transmitted from 79_seqpar_mpi/vtowfk.F90 through the call gwls_sternheimer
1011 : : ! I = input argument (allocated and filled)
1012 : : ! O = output argument (allocated)
1013 : : ! D = dummy argument (declared but not allocated. Read/Write attempts should trigger a segfault.)
1014 : : !call getghc(cpopt, T
1015 : : !psi, I
1016 : : !conjgrprj, D
1017 : : !Hpsik, O
1018 : : !gsc, D (output for PAW : <G|S|C>)
1019 : : !gs_hamk, T
1020 : : !gvnlxc, D (<G|Vnonlocal+VFockACE|C>)
1021 : : !eshift, I (<G|H-eshift.S|C>)
1022 : : !mpi_enreg, T
1023 : : !ndat, Fixed to 1 (# of FFTs to do in //)
1024 : : !dtset%prtvol, T
1025 : : !sij_opt, Fixed to 0 (PAW dependent : 0-><G|H|C> ; 1-><G|H|C> & <G|S|C> ; -1-><G|H-cte.S|C>)
1026 : : !tim_getghc, Fixed to 0 (identity of the timer of the calling subroutine. 1:cgwf 5:lobpcg)
1027 : : !type_calc) Fixed to 0 (0:whole H N:some part only)
1028 : :
1029 : : ! It is necessary to pass this optional argument to getghc if paral_kgb=1, or else the code exits cleanly with a "BUG" message...
1030 : : ! It will be important to properly understand what this means when we start using kpoints...
1031 : :
1032 [ + + ]: 26977 : if(present(psi_in)) then
1033 : :
1034 : : call getghc(cpopt,psi_in,conjgrprj,psi_out,dummy2,gs_hamk,psig4,eshift,&
1035 : 17569 : & mpi_enreg,ndat,dtset%prtvol,sij_opt,tim_getghc,type_calc)
1036 : :
1037 : : else
1038 [ + - + - : 6925434 : psig3 = psi_out
- + - - +
+ + + ]
1039 : :
1040 : : call getghc(cpopt,psig3,conjgrprj,psi_out,dummy2,gs_hamk,psig4,eshift,&
1041 : 9408 : & mpi_enreg,ndat,dtset%prtvol,sij_opt,tim_getghc,type_calc)
1042 : :
1043 : : end if
1044 [ + + ]: 26977 : if(present(cte)) then
1045 [ + + ]: 17821 : if(present(psi_in)) then
1046 [ + + + + ]: 10531628 : psi_out = psi_out - cte*psi_in
1047 : : else
1048 [ + + + + ]: 197696 : psi_out = psi_out - cte*psig3
1049 : : end if
1050 : : end if
1051 : :
1052 [ + + ]: 26977 : end subroutine Hpsik
1053 : : !!***
1054 : :
1055 : : !!****f* m_gwls_hamiltonian/Hpsikc
1056 : : !! NAME
1057 : : !! Hpsikc
1058 : : !!
1059 : : !! FUNCTION
1060 : : !! .
1061 : : !!
1062 : : !! INPUTS
1063 : : !!
1064 : : !! OUTPUT
1065 : : !!
1066 : : !! SOURCE
1067 : :
1068 : 7352 : subroutine Hpsikc(psi_out,psi_in,cte)
1069 : :
1070 : : !External variables
1071 : : complex(dp), intent(out) :: psi_out(npw_g)
1072 : : complex(dp), intent(in) :: psi_in(npw_g)
1073 : : complex(dp), intent(in), optional :: cte
1074 : :
1075 : : ! *************************************************************************
1076 : :
1077 : :
1078 [ + + ]: 1896816 : psig1(1,:) = dble(psi_in)
1079 [ + + ]: 1896816 : psig1(2,:) = dimag(psi_in)
1080 : :
1081 : 7352 : call Hpsik(psig1)
1082 : :
1083 [ + + ]: 1896816 : psi_out = dcmplx(psig1(1,:),psig1(2,:))
1084 : :
1085 [ + - + + ]: 1896816 : if(present(cte)) psi_out = psi_out - cte*psi_in
1086 : 7352 : end subroutine Hpsikc
1087 : : !!***
1088 : :
1089 : : !!!****f* m_gwls_hamiltonian/pc_k
1090 : : !!! NAME
1091 : : !!! pc_k
1092 : : !!!
1093 : : !!! FUNCTION
1094 : : !!! .
1095 : : !!!
1096 : : !!! INPUTS
1097 : : !!!
1098 : : !!! OUTPUT
1099 : : !!!
1100 : : !!! SOURCE
1101 : : !
1102 : : !subroutine pc_k(psi_inout,n,eig_e,above)
1103 : : !
1104 : : !real(dp), intent(inout) :: psi_inout(2,npw_kb)
1105 : : !integer , intent(in), optional :: n
1106 : : !real(dp), intent(in), optional :: eig_e
1107 : : !logical, intent(in), optional :: above !Has an effect only if n is also given in argument
1108 : : !
1109 : : !!Local variables
1110 : : !real(dp),parameter :: degeneracy_tolerance = 2.0e-8
1111 : : !real(dp),parameter :: projection_tolerance = 1.0e-16
1112 : : !real(dp) :: z(2)
1113 : : !
1114 : : !integer :: mpi_communicator
1115 : : !
1116 : : !! *************************************************************************
1117 : : !
1118 : : !
1119 : : !mpi_communicator = mpi_enreg%comm_bandfft
1120 : : !
1121 : : !if( present(eig_e) ) then
1122 : : ! do i = 1, nband
1123 : : ! if (abs(eig_e-eig(i)) < degeneracy_tolerance) then
1124 : : ! z(:) = scprod_k(cg(:,(i-1)*npw_k+1:i*npw_k),psi_inout)
1125 : : ! ! project it out!
1126 : : ! if ( sqrt(z(1)**2+z(2)**2) > projection_tolerance) then
1127 : : ! ! only project if z is large enough; if we project when z is
1128 : : ! ! very small, we introduce roundoff error!
1129 : : ! psi_inout(1,1:npw_k) = psi_inout(1,:) - ( z(1)*cg(1,(i-1)*npw_k+1:i*npw_k)-z(2)*cg(2,(i-1)*npw_k+1:i*npw_k) )
1130 : : ! psi_inout(2,1:npw_k) = psi_inout(2,:) - ( z(1)*cg(2,(i-1)*npw_k+1:i*npw_k)+z(2)*cg(1,(i-1)*npw_k+1:i*npw_k) )
1131 : : ! end if
1132 : : ! end if
1133 : : ! end do
1134 : : ! elseif( present(n) ) then
1135 : : ! !If there is a state "n" given in argument, then project on subspace <=n.
1136 : : !
1137 : : ! if ( n == 0) then
1138 : : ! ! if n = 0, there are no states with a lower energy! Thus, the projection vanishes.
1139 : : ! if(.not. (present(above) .and. above)) psi_inout = zero
1140 : : ! else
1141 : : ! if(present(above) .and. above) then
1142 : : ! !call projbd(cg,psi_inout,-1,0,0,istwfk(ckpt),mcg,mpi_enreg,0,n,npw_k,nspinor,dtset%ortalg,1,dummy2,scprod2,0,0,0)
1143 : : ! call projbd(cg,psi_inout,-1,0,0,istwfk(ckpt),mcg,0,n,npw_k,nspinor,dummy2,scprod2,0,0,0,mpi_enreg%me_g0,mpi_communicator)
1144 : : ! else
1145 : : ! psikb4 = psi_inout
1146 : : ! !call projbd(cg,psi_inout,-1,0,0,istwfk(ckpt),mcg,mpi_enreg,0,n,npw_k,nspinor,dtset%ortalg,1,dummy2,scprod2,0,0,0)
1147 : : ! call projbd(cg,psi_inout,-1,0,0,istwfk(ckpt),mcg,0,n,npw_k,nspinor,dummy2,scprod2,0,0,0,mpi_enreg%me_g0,mpi_communicator)
1148 : : ! psi_inout = psikb4 - psi_inout
1149 : : ! end if
1150 : : ! end if
1151 : : !else
1152 : : ! !If there is no "n" given in argument, then project on conduction states.
1153 : : ! !call projbd(cg,psi_inout,-1,0,0,istwfk(ckpt),mcg,mpi_enreg,0,nbandv,npw_k,nspinor,dtset%ortalg,1,dummy2,scprod2,0,0,0)
1154 : : ! call projbd(cg,psi_inout,-1,0,0,istwfk(ckpt),mcg,0,nbandv,npw_k,nspinor,dummy2,scprod2,0,0,0,mpi_enreg%me_g0,mpi_communicator)
1155 : : !end if
1156 : : !end subroutine pc_k
1157 : : !!!***
1158 : :
1159 : : !!****f* m_gwls_hamiltonian/g_to_r
1160 : : !! NAME
1161 : : !! g_to_r
1162 : : !!
1163 : : !! FUNCTION
1164 : : !! .
1165 : : !!
1166 : : !! INPUTS
1167 : : !!
1168 : : !! OUTPUT
1169 : : !!
1170 : : !! SOURCE
1171 : :
1172 : 3385 : subroutine g_to_r(psi_out,psi_in)
1173 : :
1174 : : real(dp), intent(out) :: psi_out(2,n4,n5,n6)
1175 : : real(dp), intent(in) :: psi_in(2,npw_g)
1176 : : integer :: option, cplex
1177 : : integer :: nproc_fft, me_fft, nd3 !, ierr
1178 : :
1179 : : ! *************************************************************************
1180 : :
1181 : 3385 : option = 0 ! fft wavefunction to real space
1182 : 3385 : cplex = 2 ! complex potential
1183 : :
1184 [ + - + - : 2132417 : psig4 = psi_in
- + - - +
+ + + ]
1185 [ + + + + : 67209175 : psi_out = zero
+ + + + ]
1186 : : call fourwf(cplex,dummy3,psig4,dummy2,psi_out,gbound,gbound,istwfk(ckpt),kg_k_gather,kg_k_gather,mgfft,mpi_enreg, &
1187 [ - + - + ]: 3385 : 1,ngfft,npw_g,npw_g,n4,n5,n6,option,tim_fourwf,weight,weight)
1188 [ + + + + : 67209175 : psi_out = psi_out/sqrt(ucvol)
+ + + + ]
1189 : :
1190 : : !! This comes from prep_fourwf
1191 : : !nproc_fft=mpi_enreg%nproc_fft
1192 : : !if (nproc_fft>1) then
1193 : : ! me_fft=mpi_enreg%me_fft
1194 : : ! if (me_fft>0) then
1195 : : ! nd3=(ngfft(3)-1)/nproc_fft+1
1196 : : ! psi_out(:,:,:,me_fft*nd3+1:me_fft*nd3+nd3)=psi_out(:,:,:,1:nd3)
1197 : : ! psi_out(:,:,:,1:nd3)=zero
1198 : : ! end if
1199 : : ! call xmpi_sum(psi_out,mpi_enreg%comm_fft,ierr)
1200 : : !end if
1201 : :
1202 : : !Instead of communications the whole real space vector on all comm_fft CPUs,
1203 : : !it is possible to let each CPU keep it's part only and communicate only the sums.
1204 : : !Then, however, we need to clean the trash in the part of the real space
1205 : : !vector that's not attributed to the given comm_fft CPU.
1206 : 3385 : nproc_fft=mpi_enreg%nproc_fft
1207 [ + + ]: 3385 : if (nproc_fft>1) then
1208 : 1256 : me_fft=mpi_enreg%me_fft
1209 [ + + ]: 1256 : if (me_fft>0) then
1210 : 628 : nd3=(ngfft(3)-1)/nproc_fft+1
1211 [ + - + + : 12468940 : psi_out(:,:,:,me_fft*nd3+1:me_fft*nd3+nd3)=psi_out(:,:,:,1:nd3)
+ + + + +
+ + + + +
+ + + + ]
1212 [ + + + + : 6234784 : psi_out(:,:,:,1:nd3)=zero
+ + + + ]
1213 : : end if
1214 : : !!! call xmpi_sum(psi_out,mpi_enreg%comm_fft,ierr)
1215 : : end if
1216 : :
1217 : 3385 : end subroutine g_to_r
1218 : : !!***
1219 : :
1220 : : !!****f* m_gwls_hamiltonian/gr_to_g
1221 : : !! NAME
1222 : : !! gr_to_g
1223 : : !!
1224 : : !! FUNCTION
1225 : : !! .
1226 : : !!
1227 : : !! INPUTS
1228 : : !!
1229 : : !! OUTPUT
1230 : : !!
1231 : : !! SOURCE
1232 : :
1233 : 5199 : subroutine gr_to_g(psig_out,psir_in,psig_in)
1234 : :
1235 : : real(dp), intent(in) :: psir_in(2,n4,n5,n6)
1236 : : real(dp), intent(in), optional :: psig_in(2,npw_g)
1237 : : real(dp), intent(out) :: psig_out(2,npw_g)
1238 : :
1239 : : integer :: i1, i2, i3
1240 : : integer :: cplex, option
1241 : :
1242 : : ! *************************************************************************
1243 : :
1244 : 5269 : cplex = 2 ! complex potential
1245 : 5269 : option= 2 ! multiply wavefunction by potential
1246 : :
1247 [ + + ]: 5269 : if(.not. present(psig_in)) then
1248 [ + + + + ]: 46330 : psig4(:,:) = psig_out(:,:)
1249 : : else
1250 [ + + + + ]: 3302766 : psig4(:,:) = psig_in(:,:)
1251 : : end if
1252 : :
1253 [ + + ]: 100111 : do i3=1,n6
1254 [ + + ]: 1902109 : do i2=1,n5
1255 [ + + ]: 36134802 : do i1=1,n4
1256 : 34237962 : denpot(2*i1-1,i2,i3)= psir_in(1,i1,i2,i3)
1257 : 36039960 : denpot(2*i1 ,i2,i3)= psir_in(2,i1,i2,i3)
1258 : : end do
1259 : : end do
1260 : : end do
1261 : :
1262 : : call fourwf( cplex, & ! complex potential
1263 : : denpot, & ! real space wavefunction, in denpot format
1264 : : psig4, & ! fourier space wavefunction
1265 : : psig_out, & ! result, in FFT configuration
1266 : : psir3,gbound,gbound,istwfk(ckpt),kg_k_gather,kg_k_gather,mgfft,mpi_enreg,1, & ! Various other arguments
1267 [ - + - + ]: 5269 : ngfft,npw_g,npw_g,n4,n5,n6,option,tim_fourwf,weight,weight)
1268 : :
1269 [ + + ]: 5269 : end subroutine gr_to_g
1270 : : !!***
1271 : :
1272 : : !!****f* m_gwls_hamiltonian/kbkb_to_kb
1273 : : !! NAME
1274 : : !! kbkb_to_kb
1275 : : !!
1276 : : !! FUNCTION
1277 : : !! .
1278 : : !!
1279 : : !! INPUTS
1280 : : !!
1281 : : !! OUTPUT
1282 : : !!
1283 : : !! SOURCE
1284 : :
1285 : 70 : subroutine kbkb_to_kb(psik_out,psik_in_1,psik_in_2)
1286 : : !----------------------------------------------------------------------------------------------------
1287 : : ! This function computes the direct product of two wavefunctions in real space,
1288 : : ! psi_out(r) = psi_in_1^*(r)*psi_in_2(r) (without complex conjugating any of the 2 wavefunctions)
1289 : : ! and returns the result in fourier space, psi_out(k).
1290 : : !
1291 : : ! The two input wavefunctions are in k space.
1292 : : !
1293 : : !
1294 : : !----------------------------------------------------------------------------------------------------
1295 : : real(dp), intent(out) :: psik_out(2,npw_kb)
1296 : : real(dp), intent(inout) :: psik_in_1(2,npw_kb), psik_in_2(2,npw_kb)
1297 : :
1298 : : ! *************************************************************************
1299 : :
1300 : : ! change configuration of the data : LA -> FFT
1301 : 70 : call wf_block_distribute(psik_in_1, psig1,1)
1302 : 70 : call wf_block_distribute(psik_in_2, psig2,1)
1303 : :
1304 : : ! Fourier transform the first input
1305 : 70 : call g_to_r(psir1, psig1)
1306 : :
1307 : : ! Complex conjugate in real space the first input
1308 [ + + + + : 480130 : psir1(2,:,:,:) = -psir1(2,:,:,:)
+ + ]
1309 : :
1310 : : ! Fourrier transform the second input, multiply component-wise
1311 : 70 : call gr_to_g(psig2,psir1)
1312 : :
1313 : : ! change configuration of the output : FFT -> LA
1314 : 70 : call wf_block_distribute(psik_out, psig2,2)
1315 : :
1316 : 70 : end subroutine kbkb_to_kb
1317 : : !!***
1318 : :
1319 : : !!****f* m_gwls_hamiltonian/build_vxc
1320 : : !! NAME
1321 : : !! build_vxc
1322 : : !!
1323 : : !! FUNCTION
1324 : : !! .
1325 : : !!
1326 : : !! INPUTS
1327 : : !!
1328 : : !! OUTPUT
1329 : : !!
1330 : : !! SOURCE
1331 : :
1332 : 8 : subroutine build_vxc(vxc2,nfft2,nspden2)
1333 : : !Only transcribe the argument vxc2 in the module; the change from dg to sg is done in build_H (and stored in vxc), since the
1334 : : !arguments of fftpac are built in build_H.
1335 : :
1336 : : !We need the dimensions of vxc since they don't exist yet in the module; build_vxc being called before build_H.
1337 : : integer, intent(in) :: nfft2, nspden2
1338 : : real(dp), intent(in) :: vxc2(nfft2,nspden2)
1339 : :
1340 : : ! *************************************************************************
1341 : :
1342 [ - + + - : 32 : ABI_MALLOC(vxc_dg,(nfft2,nspden2))
- + + - +
- + - - +
- + - + ]
1343 [ - + + + : 35016 : vxc_dg = vxc2
+ + ]
1344 : :
1345 : 8 : end subroutine build_vxc
1346 : : !!***
1347 : :
1348 : : !!****f* m_gwls_hamiltonian/destroy_H
1349 : : !! NAME
1350 : : !! destroy_H
1351 : : !!
1352 : : !! FUNCTION
1353 : : !! .
1354 : : !!
1355 : : !! INPUTS
1356 : : !!
1357 : : !! OUTPUT
1358 : : !!
1359 : : !! SOURCE
1360 : :
1361 : 8 : subroutine destroy_H
1362 : :
1363 : 8 : call dtset%free()
1364 : 8 : call gs_hamk%free()
1365 : :
1366 : 8 : call cryst%free()
1367 : 8 : call Kmesh%free()
1368 : 8 : call Qmesh%free()
1369 : 8 : call Gsphere%free()
1370 : 8 : call Vcp%free()
1371 : :
1372 : 8 : call bandfft_kpt_destroy_array(bandfft_kpt,mpi_enreg)
1373 : 8 : call destroy_mpi_enreg(mpi_enreg)
1374 : :
1375 [ + - ]: 8 : ABI_SFREE(cg)
1376 [ + - ]: 8 : ABI_SFREE(gbound)
1377 [ + - ]: 8 : ABI_SFREE(kg_k)
1378 [ + - ]: 8 : ABI_SFREE(ffnl)
1379 [ + - ]: 8 : ABI_SFREE(ph3d)
1380 [ + - ]: 8 : ABI_SFREE(kinpw)
1381 [ + - ]: 8 : ABI_SFREE(vxc)
1382 [ + - ]: 8 : ABI_SFREE(vlocal)
1383 [ + - - + : 8 : ABI_SFREE(conjgrprj)
- - - - -
+ ]
1384 [ + - ]: 8 : ABI_SFREE(istwfk)
1385 [ + - ]: 8 : ABI_SFREE(dummy2)
1386 [ + - ]: 8 : ABI_SFREE(dummy3)
1387 [ + - ]: 8 : ABI_SFREE(eig)
1388 [ + - ]: 8 : ABI_SFREE(scprod2)
1389 [ + - ]: 8 : ABI_SFREE(pcon)
1390 [ + - ]: 8 : ABI_SFREE(psik1)
1391 [ + - ]: 8 : ABI_SFREE(psik2)
1392 [ + - ]: 8 : ABI_SFREE(psik3)
1393 [ + - ]: 8 : ABI_SFREE(psik4)
1394 [ + - ]: 8 : ABI_SFREE(psikb1)
1395 [ + - ]: 8 : ABI_SFREE(psikb2)
1396 [ + - ]: 8 : ABI_SFREE(psikb3)
1397 [ + - ]: 8 : ABI_SFREE(psikb4)
1398 [ + - ]: 8 : ABI_SFREE(psig1)
1399 [ + - ]: 8 : ABI_SFREE(psig2)
1400 [ + - ]: 8 : ABI_SFREE(psig3)
1401 [ + - ]: 8 : ABI_SFREE(psig4)
1402 [ + - ]: 8 : ABI_SFREE(psir1)
1403 [ + - ]: 8 : ABI_SFREE(psir2)
1404 [ + - ]: 8 : ABI_SFREE(psir3)
1405 [ + - ]: 8 : ABI_SFREE(psidg)
1406 [ + - ]: 8 : ABI_SFREE(vxc_dg)
1407 [ + - ]: 8 : ABI_SFREE(denpot)
1408 [ + - ]: 8 : ABI_SFREE(kernel_wavefunctions_FFT)
1409 [ + - ]: 8 : ABI_SFREE(valence_wavefunctions_FFT)
1410 [ + - ]: 8 : if(associated(gvec)) then
1411 : 8 : ABI_FREE(gvec)
1412 : : end if
1413 [ + - ]: 8 : ABI_SFREE(vc_sqrt)
1414 : :
1415 : 8 : end subroutine destroy_H
1416 : : !!***
1417 : :
1418 : : !!****f* m_gwls_hamiltonian/build_H
1419 : : !! NAME
1420 : : !! build_H
1421 : : !!
1422 : : !! FUNCTION
1423 : : !! Arguments of gw_sternheimer, received as argument by build_H
1424 : : !!
1425 : : !! INPUTS
1426 : : !!
1427 : : !! OUTPUT
1428 : : !!
1429 : : !! SOURCE
1430 : :
1431 : 8 : subroutine build_H(dtset2,mpi_enreg2,cpopt2,cg2,gs_hamk2,kg_k2,kinpw2)
1432 : :
1433 : : use m_wfutils
1434 : :
1435 : : type(dataset_type), intent(in) :: dtset2
1436 : : type(MPI_type), intent(in) :: mpi_enreg2
1437 : : type(gs_hamiltonian_type), intent(inout) :: gs_hamk2
1438 : :
1439 : : integer, intent(in) :: cpopt2
1440 : : integer, intent(in) :: kg_k2(3,gs_hamk2%npw_k)
1441 : : !Since mcg = npw_k*nband when there is only gamma, the next line works. If there is not only Gamma, mcg is the proper size of cg.
1442 : : real(dp), intent(in) :: cg2(2,dtset2%mpw*dtset2%nspinor*dtset2%mband*dtset2%mkmem*dtset2%nsppol)
1443 : : real(dp), intent(in) :: kinpw2(gs_hamk2%npw_k)
1444 : : !Local variables : most of them are in the module for now.
1445 : : real(dp) :: commutation_error
1446 : : integer :: io_unit
1447 : : integer :: io_unit_debug
1448 : : integer :: ierr
1449 : : integer :: cplx
1450 : : integer :: j, k
1451 : : integer :: dimph3d
1452 : : integer :: mb
1453 : :
1454 : : integer :: mpi_communicator
1455 : :
1456 : : character(128):: filename_debug
1457 : :
1458 : :
1459 : 8 : real(dp), allocatable :: wfk_tmp1(:,:) ,wfk_tmp2(:,:)
1460 : :
1461 : : ! *************************************************************************
1462 : :
1463 : : ! Hartree-Fock cannot be used with GWLS.
1464 [ - + - - ]: 8 : if(dtset2%usefock==1 .and. associated(gs_hamk2%fockcommon)) then
1465 : 0 : ABI_ERROR(' build_H : Hartree-Fock option can not be used with optdriver==66 (GWLS calculations).')
1466 : : end if
1467 : :
1468 : : !First we copy the data structure types
1469 [ - + - + : 8 : dtset = dtset2%copy()
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + ]
1470 : :
1471 : 8 : call copy_mpi_enreg(mpi_enreg2,mpi_enreg)
1472 : :
1473 : 8 : call gs_hamk2%copy(gs_hamk)
1474 : :
1475 : : !Then we copy the standard types
1476 : 8 : cpopt = cpopt2
1477 : 8 : npw_k = gs_hamk2%npw_k
1478 : :
1479 [ - + + - : 24 : ABI_MALLOC(cg,(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%mkmem*dtset%nsppol))
+ - + - -
+ - + -
+ ]
1480 [ + - - + : 38566 : cg = cg2
- - + + +
+ ]
1481 : :
1482 [ - + + - : 48 : ABI_MALLOC(vlocal,(gs_hamk2%n4,gs_hamk2%n5,gs_hamk2%n6,gs_hamk2%nvloc))
- + + - -
+ + - - +
+ - + - +
- - + - +
- + ]
1483 [ + - + - : 54888 : vlocal = gs_hamk2%vlocal
+ - + - -
+ - - - -
- - - - -
- + + + +
+ + + + ]
1484 : 8 : gs_hamk%vlocal => vlocal
1485 : :
1486 [ - + + - : 24 : ABI_MALLOC(kg_k,(3,npw_k))
+ - + - -
+ - + -
+ ]
1487 [ + - - + : 5156 : kg_k = kg_k2
- - + + +
+ ]
1488 [ - + + - : 24 : ABI_MALLOC(kinpw,(npw_k))
+ - + - -
+ - + -
+ ]
1489 [ + - - + : 1301 : kinpw = kinpw2
- - + + ]
1490 : :
1491 [ + - ]: 8 : dimffnl=0; if (blocksize<=1) dimffnl=size(gs_hamk2%ffnl_k,2)
1492 [ - + + - : 48 : ABI_MALLOC(ffnl,(npw_k,dimffnl,gs_hamk%lmnmax,gs_hamk%ntypat))
- + + - -
+ + - - +
+ - + - +
- - + - +
- + ]
1493 [ + - ]: 8 : dimph3d=0; if (blocksize<=1) dimph3d=gs_hamk2%matblk
1494 [ - + + - : 32 : ABI_MALLOC(ph3d,(2,npw_k,dimph3d))
- + + - +
- + - - +
- + - + ]
1495 : :
1496 : : !Initializing variables from dataset
1497 : 8 : nfft = dtset%nfft
1498 : 8 : nline = dtset%nline
1499 : 8 : tolwfr = dtset%tolwfr
1500 [ + + ]: 152 : ngfft = dtset%ngfft
1501 : 8 : mcg = dtset%mpw*dtset%nspinor*dtset%mband*dtset%mkmem*dtset%nsppol
1502 : 8 : nspinor=dtset%nspinor
1503 : 8 : n1=ngfft(1)
1504 : 8 : n2=ngfft(2)
1505 : 8 : n3=ngfft(3)
1506 : 8 : n4=ngfft(4)
1507 : 8 : n5=ngfft(5)
1508 : 8 : n6=ngfft(6)
1509 [ + + ]: 32 : mgfft=maxval(ngfft(1:3))
1510 : 8 : nbandv = int(dtset%nelect)/2
1511 [ - + + - : 24 : ABI_MALLOC(istwfk,(dtset%nkpt))
+ - + - -
+ - + -
+ ]
1512 [ + + ]: 16 : istwfk(:)=dtset%istwfk
1513 : :
1514 : : !Initializing variables from gs_hamk
1515 : 8 : ucvol = gs_hamk%ucvol
1516 [ + - - + : 32 : ABI_MALLOC(gbound,(2*mgfft+8,2))
+ - + - +
- + - - +
- + - + ]
1517 : : !gbound = gs_hamk%gbound_k !Must be done later for bandft parallelism
1518 : :
1519 : : !Parameters which need to be set by hand for now...
1520 : 8 : weight = 1 ! The weight of the k-pts, which sum to 1.
1521 : 8 : tim_fourwf = 0
1522 : 8 : ckpt = 1 ! The kpt of the wf to FFT. We only consider gamma point for now.
1523 : :
1524 : : ! ndat = 1 used to be hard coded, which works fine for FFT only parallelism.
1525 : 8 : ndat = 1 ! # of FFT to do in parallel in fourwf
1526 : :
1527 : 8 : eshift = 0.0 ! For PAW, opt_sij=-1 gives <G|H-lambda.S|C> in ghc instead of <G|H|C>
1528 : 8 : sij_opt = 0 ! Option in PAW to tell getghc what to compute...
1529 : 8 : tim_getghc = 0 ! timing code of the calling subroutine(can be set to 0 if not attributed)
1530 : 8 : type_calc = 0 ! option governing which part of Hamitonian is to be applied: 0: whole Hamiltonian
1531 : 8 : nband = dtset%mband
1532 : 8 : ispden = 1 !When required, the spin index to be used. We don't support spin polarized calculations yet...
1533 : :
1534 : :
1535 : :
1536 : : !========================================================================================================================
1537 : : ! Trying to implement band parallelism (Bruno, 14/10/2013)
1538 : : !------------------------------------------------------------------------------------------------------------------------
1539 : : !
1540 : : ! Band parallelism is described in the article on the LOBPCG method by F. Bottin et al,
1541 : : ! "Large scale ab initio calculations based on three levels of parallelisation", Computational Materials Science 42 (2008) 329-336
1542 : : !
1543 : : ! The article describes the ABINIT implementation specifically, suggesting that the information there is directly related
1544 : : ! to the code.
1545 : : !
1546 : : ! The main points in order to understand band + FFT parallelism are:
1547 : : !
1548 : : ! 1) The processors are arranged in a 2D Cartesian MPI topology, or dimensions M x P, with
1549 : : ! M = nproc_bands
1550 : : ! P = nproc_fft
1551 : : ! There are of course M x P processors
1552 : : !
1553 : : ! 2) the wavefunction coefficients (namely the array cg) are distributed on these processors. Unfortunately,
1554 : : ! two different distribution schemes are necessary: one for linear algebra (matrix products, etc), and one
1555 : : ! consistent with the Goedecker FFTs. The code must thus change the data distribution back and forth.
1556 : : !
1557 : : ! 3) the "linear algebra" distribution describes the array cg directly. The G vectors are distributed among all
1558 : : ! M x P processors, such that npw = npw_tot / (nproc_bands x nproc_fft). Every processor has information about
1559 : : ! all bands. Schematically:
1560 : : !
1561 : : !
1562 : : ! <- P = nproc_fft ->
1563 : : ! ----------------------------------
1564 : : ! | n | n | n | n | ( for all band indices n)
1565 : : ! ^ | G_11 | ... | ... | G_P1 |
1566 : : ! | ----------------------------------
1567 : : ! M = nproc_bands | n | n | n | n |
1568 : : ! | | G_1. | ... | ... | G_P. |
1569 : : ! v ----------------------------------
1570 : : ! | n | n | n | n |
1571 : : ! | G_1M | ... | ... | G_PM |
1572 : : ! ----------------------------------
1573 : : !
1574 : : !
1575 : : ! the LOBPCG algorithm acts on blocks of bands. Thus, although each processor has information about all bands,
1576 : : ! we must conceptually view the bands grouped in blocks of size M, as {c_{1}(G),...,c_{M}(G)},
1577 : : ! {c_{M+1}(G)...,c_{2M}(G)}, ...
1578 : : !
1579 : : ! With this conceptual grouping, for a given block each processor has M x NG/(M x P) coefficients, where NG is the
1580 : : ! total number of G-vectors.
1581 : : !
1582 : : ! 4) The distribution of information above is not appropriate for parallel FFTs. The data for one block is thus
1583 : : ! transposed and takes the form
1584 : : !
1585 : : ! <- P = nproc_fft ->
1586 : : ! ----------------------------------
1587 : : ! | 1 | 1 | ... | 1 |
1588 : : ! ^ | G_1 | G_2 | ... | G_P |
1589 : : ! | ----------------------------------
1590 : : ! M = nproc_bands | .. | ... | ... | ... |
1591 : : ! | | G_1 | G_2 | ... | G_P |
1592 : : ! v ----------------------------------
1593 : : ! | M | M | ... | M |
1594 : : ! | G_1 | G_2 | ... | G_P |
1595 : : ! ----------------------------------
1596 : : !
1597 : : ! where the set of G vectors G_i = (G_{i1}, G_{i2}, ..., G_{iM}). Thus, a given processor has information about a single
1598 : : ! band, but more G vectors. Each processor has
1599 : : ! NG/(M x P) x M = NG/P coefficients, just like before.
1600 : : ! Also, it is clear that the information is only communicated in the columns of the diagram above, avoiding
1601 : : ! "all processors to all processors" communication.
1602 : : !
1603 : : ! The data is now distributed properly to do parallel FFTs! Each row in the diagram above corresponds to FFTs done
1604 : : ! in parallel over nproc_fft processors, on a given band. There are M rows running thus in parallel!
1605 : : !
1606 : : ! The underlying ABINIT routines are equipped to handle FFT parallelism, not band distributed parallelism.
1607 : : ! prep_getghc.F90 and lobpgcwf.F90 show how to rearange information to be able to apply basic ABINIT routines.
1608 : : !
1609 : : ! The code below is inspired / guessed from lobpcgwf and prep_getghc. WE ASSUME THERE IS NO SPINORS! CODE SHOULD
1610 : : ! BE HEAVILY REVIEWED for k-points and spinors, if and when they come to be useful.
1611 : : !
1612 : : !========================================================================================================================
1613 : :
1614 : : ! variables for band parallelism, following the language in lobpcgwf
1615 : 8 : nspinor = 1 ! how many spinors are present. Hardcoded to 1 for now.
1616 : 8 : blocksize = mpi_enreg%nproc_band*mpi_enreg%bandpp ! how many bands treated in a block; # of FFT done in parallel in getghc
1617 : 8 : nbdblock = nband/blocksize ! how many blocks of bands are there
1618 : 8 : ikpt_this_proc = 1 ! Assuming only 1 kpoint, for molecules.
1619 : : ! This will have to be reviewed for crystals!
1620 : :
1621 : 8 : npw_kb = npw_k*blocksize
1622 : 8 : npw_g = gs_hamk2%npw_fft_k
1623 : :
1624 [ + + ]: 8 : if (blocksize>1) then
1625 : 4 : kg_k_gather => bandfft_kpt(ikpt_this_proc)%kg_k_gather
1626 : 4 : ffnl_gather => bandfft_kpt(ikpt_this_proc)%ffnl_gather
1627 : 4 : ph3d_gather => bandfft_kpt(ikpt_this_proc)%ph3d_gather
1628 : 4 : kinpw_gather => bandfft_kpt(ikpt_this_proc)%kinpw_gather
1629 : : else
1630 [ + - + - : 6232 : ffnl = gs_hamk2%ffnl_k
+ - + - -
+ - - - -
- - - - -
- + + + +
+ + + + ]
1631 [ + - + - : 15448 : ph3d = gs_hamk2%ph3d_k
+ - - + -
- - - - -
- - + + +
+ + + ]
1632 : 4 : kg_k_gather => kg_k
1633 : 4 : ffnl_gather => ffnl
1634 : 4 : ph3d_gather => ph3d
1635 : 4 : kinpw_gather => kinpw
1636 : : endif
1637 : 8 : call gs_hamk%load_k(kinpw_k=kinpw_gather,kg_k=kg_k_gather,ffnl_k=ffnl_gather,ph3d_k=ph3d_gather)
1638 : :
1639 [ + - + - : 736 : gbound = gs_hamk%gbound_k
- + - - -
- - - + +
+ + ]
1640 : :
1641 : : !Set up wfk routines
1642 : 8 : call set_wf(ucvol/nfft,n4,n5,n6,npw_k,blocksize,npw_g,mpi_enreg%comm_bandfft,mpi_enreg%comm_fft,mpi_enreg%comm_band)
1643 : :
1644 : : ! prepare the valence wavefunctions and projection operator to work in band+FFT parallel
1645 : 8 : call DistributeValenceWavefunctions()
1646 : 8 : call DistributeValenceKernel()
1647 : :
1648 : 8 : cplx = 2 ! wavefunctions have complex coefficients
1649 : :
1650 : : ! Initialize the dummy variables
1651 [ - + - + ]: 8 : ABI_MALLOC(conjgrprj,(0,0))
1652 [ - + - + ]: 8 : ABI_MALLOC(dummy2,(0,0))
1653 [ - + - + ]: 8 : ABI_MALLOC(dummy3,(0,0,0))
1654 : :
1655 : : !Initialisation of the total counter for iterations of SQMR :
1656 : 8 : ktot = 0
1657 : :
1658 : : !Allocations of working arrays for the module
1659 : : !- for pc_k function
1660 [ - + + - : 24 : ABI_MALLOC(scprod2,(2,nband))
+ - + - -
+ - + -
+ ]
1661 : :
1662 : : !- for precondition function (and set_precondition subroutine)
1663 [ - + + - : 24 : ABI_MALLOC(pcon,(npw_g))
+ - + - -
+ - + -
+ ]
1664 [ + + ]: 1550 : pcon = one
1665 : :
1666 : : !- for (private) working wf
1667 [ - + + - : 24 : ABI_MALLOC(psik1,(2,npw_k))
+ - + - -
+ - + -
+ ]
1668 [ - + + - : 16 : ABI_MALLOC(psik2,(2,npw_k))
- + - + -
+ ]
1669 [ - + + - : 16 : ABI_MALLOC(psik3,(2,npw_k))
- + - + -
+ ]
1670 [ - + + - : 16 : ABI_MALLOC(psik4,(2,npw_k))
- + - + -
+ ]
1671 [ - + + - : 24 : ABI_MALLOC(psikb1,(2,npw_kb))
+ - + - -
+ - + -
+ ]
1672 [ - + + - : 16 : ABI_MALLOC(psikb2,(2,npw_kb))
- + - + -
+ ]
1673 [ - + + - : 16 : ABI_MALLOC(psikb3,(2,npw_kb))
- + - + -
+ ]
1674 [ - + + - : 16 : ABI_MALLOC(psikb4,(2,npw_kb))
- + - + -
+ ]
1675 [ - + + - : 24 : ABI_MALLOC(psig1,(2,npw_g))
+ - + - -
+ - + -
+ ]
1676 [ - + + - : 16 : ABI_MALLOC(psig2,(2,npw_g))
- + - + -
+ ]
1677 [ - + + - : 16 : ABI_MALLOC(psig3,(2,npw_g))
- + - + -
+ ]
1678 [ - + + - : 16 : ABI_MALLOC(psig4,(2,npw_g))
- + - + -
+ ]
1679 [ - + + - : 40 : ABI_MALLOC(psir1,(2,n4,n5,n6))
- + + - -
+ + - + -
+ - - + -
+ - + ]
1680 [ - + + - : 32 : ABI_MALLOC(psir2,(2,n4,n5,n6))
- + + - -
+ + - - +
- + - + ]
1681 [ - + + - : 32 : ABI_MALLOC(psir3,(2,n4,n5,n6))
- + + - -
+ + - - +
- + - + ]
1682 [ - + + - : 24 : ABI_MALLOC(psidg,(2,nfft))
+ - + - -
+ - + -
+ ]
1683 [ + - - + : 40 : ABI_MALLOC(denpot,(2*n4,n5,n6))
+ - - + +
- - + + -
+ - + - -
+ - + -
+ ]
1684 : :
1685 [ + + + + : 158840 : psir1 = zero
+ + + + ]
1686 [ + + + + : 158840 : psir2 = zero
+ + + + ]
1687 [ + + + + : 158840 : psir3 = zero
+ + + + ]
1688 [ + + + + : 106856 : denpot = zero
+ + ]
1689 : :
1690 : : !Construct the vector of eigenvalues and write then to std output
1691 [ - + + - : 24 : ABI_MALLOC(eig,(nband))
+ - + - -
+ - + -
+ ]
1692 [ + + ]: 88 : eig=zero
1693 : :
1694 : 8 : write(std_out,*) ch10,"Eigenvalues computation check, routine build_H:",ch10
1695 : 8 : io_unit_debug = get_unit()
1696 : 8 : write(filename_debug,'(A,I0.4,A)') "DEBUG_PROC=",mpi_enreg%me,".dat"
1697 : :
1698 : :
1699 : :
1700 : 8 : mpi_communicator = mpi_enreg%comm_bandfft
1701 : :
1702 : 8 : open(file=filename_debug,status=files_status_old,unit=io_unit_debug)
1703 : :
1704 : 8 : write(io_unit_debug,'(A)') " Parameters:"
1705 : 8 : write(io_unit_debug,'(A,I5)') " nband = ", nband
1706 : 8 : write(io_unit_debug,'(A,I5)') " blocksize = ", blocksize
1707 : 8 : write(io_unit_debug,'(A,I5)') " npw_k = ", npw_k
1708 : 8 : write(io_unit_debug,'(A,I5)') " nbdblock = ", nbdblock
1709 : :
1710 : : ! temporary wavefunction array, for data in the "linear algebra" distribution
1711 [ - + + - : 24 : ABI_MALLOC( wfk_tmp1, (2,npw_k))
+ - + - -
+ - + ]
1712 [ - + + - : 16 : ABI_MALLOC( wfk_tmp2, (2,npw_k))
- + - + ]
1713 : :
1714 [ + + ]: 88 : do n=1, nband
1715 : : ! Extract i^t/h wavefunction
1716 [ + + + + ]: 38630 : wfk_tmp1(:,1:npw_k) = cg(:,(n-1)*npw_k+1:n*npw_k)
1717 : :
1718 : : ! Are the wavefunctions normalized?
1719 : : !tmpc = cg_zdotc(npw_k,wfk_tmp1,wfk_tmp1)
1720 : : !call xmpi_sum(tmpc,mpi_enreg%comm_bandfft,ierr) ! sum on all processors
1721 : :
1722 : : ! DEBUGGING CODE
1723 : 80 : write(std_out,'(A,I5,A,2F24.16)') "band ", n, ", <psi_n | psi_n > =", norm_k(wfk_tmp1)
1724 : 80 : write(io_unit_debug,'(A,I5,A,2F24.16)') "band ", n, ", <psi_n | psi_n > =", norm_k(wfk_tmp1)
1725 : 88 : flush(io_unit_debug)
1726 : : end do
1727 : :
1728 : :
1729 : : ! loop on blocks of bands. All bands in a given block will be done in parallel!
1730 : :
1731 : : ! loop on block of bands
1732 [ + + ]: 68 : do iblock = 1, nbdblock
1733 : :
1734 : : ! loop on states for this block
1735 [ + + ]: 140 : do iband = 1, blocksize
1736 : :
1737 : 80 : n = (iblock-1)*blocksize+iband
1738 : :
1739 [ + + + + ]: 38690 : psikb1(:,(iband-1)*npw_k+1:iband*npw_k) = cg(:,(n-1)*npw_k+1:n*npw_k)
1740 : :
1741 : : end do
1742 : :
1743 : : ! change configuration of the data
1744 : 60 : call wf_block_distribute(psikb1, psig1,1) ! LA -> FFT
1745 : :
1746 : : ! Apply hamiltonian on wavefunction. In bandFFT parallel, Hpsik calls prep_getghc, which knows how to transform the
1747 : : ! distribution of the data from "linear algebra"-like to "FFT"-like. The output is *probably* in the "linear algebra"-like
1748 : : ! distribution.
1749 : 60 : call Hpsik(psig2,psig1)
1750 : :
1751 : : ! change configuration of the data
1752 : 60 : call wf_block_distribute(psikb2, psig2,2) ! LA -> FFT
1753 : :
1754 : : ! extract the wavefunctions band by band
1755 [ + + ]: 148 : do iband=1, blocksize
1756 : :
1757 : 80 : n = blocksize*(iblock-1) + iband ! band index
1758 : :
1759 [ + + + + ]: 38630 : wfk_tmp1(:,1:npw_k) = psikb1(:,(iband-1)*npw_k+1:iband*npw_k)
1760 [ + + + + ]: 38630 : wfk_tmp2(:,1:npw_k) = psikb2(:,(iband-1)*npw_k+1:iband*npw_k)
1761 : :
1762 : 80 : tmpc = cg_zdotc(npw_k,wfk_tmp1,wfk_tmp2)
1763 : :
1764 : 80 : call xmpi_sum(tmpc,mpi_enreg%comm_bandfft,ierr) ! sum on all processors
1765 : 80 : eig(n) = tmpc(1)
1766 : :
1767 : 80 : write(std_out,'(A,I5,A,F24.16,A)') "(build_H) band ", n, ", eig =", eig(n), " Ha."
1768 : :
1769 : : ! DEBUGGING CODE
1770 : 80 : write(io_unit_debug,'(A,I5,A,F24.16,A)') "band ", n, ", eig =", eig(n), " Ha."
1771 : 80 : flush(io_unit_debug)
1772 : 140 : flush(io_unit_debug)
1773 : : end do
1774 : :
1775 : : end do
1776 : :
1777 [ - + ]: 8 : ABI_FREE( wfk_tmp1 )
1778 [ - + ]: 8 : ABI_FREE( wfk_tmp2 )
1779 : 8 : close(io_unit_debug)
1780 : :
1781 : :
1782 : :
1783 : : ! Finishing the construction of vxc (transcribing it from the double real grid (for the density)
1784 : : ! to the single real grid (for the wfs).
1785 : : ! Assumes we only need one spin component; one transcription per spin being needed.
1786 [ + - ]: 8 : if(allocated(vxc_dg)) then
1787 [ - + + - : 48 : ABI_MALLOC(vxc,(n4,n5,n6,dtset%nspden))
- + + - -
+ + - - +
+ - + - +
- - + - +
- + ]
1788 [ + + + + : 54880 : vxc = zero
+ + + + ]
1789 : 8 : call fftpac(ispden,mpi_enreg,dtset%nspden,n1,n2,n3,n4,n5,n6,dtset%ngfft,vxc_dg(:,ispden),vxc(:,:,:,ispden),2)
1790 : : end if
1791 : :
1792 : 8 : timrev = 1 !Assumes istwfk *1. 1:time reversal symmetry NOT present | 2:" " " present
1793 [ - + + - : 24 : ABI_MALLOC(title,(dtset%ntypat))
+ - + - -
+ - + ]
1794 [ + + ]: 24 : do i=1,dtset%ntypat
1795 : 24 : title(i) = "Bloup" ! The clean way would be to get the psps structure in this module
1796 : : ! (build_vxc is called from a place in GS calculations where it is available;
1797 : : ! should be the easiest way). For now, this allows the code to run.
1798 : : end do
1799 : : call cryst%init(dtset%amu_orig(:,1),dtset%spgroup,dtset%natom,dtset%npsp,&
1800 : : dtset%ntypat,dtset%nsym,dtset%rprimd_orig(:,:,1),dtset%typat,&
1801 : : dtset%xred_orig(:,:,1),dtset%ziontypat,dtset%znucl,timrev,.false.,.false.,title,&
1802 [ - + ]: 8 : dtset%symrel,dtset%tnons,dtset%symafm)
1803 [ - + ]: 8 : ABI_FREE(title)
1804 : 8 : call Cryst%print()
1805 : :
1806 : : !TODO : Should be put in a separate build_vc constructor, and should be called right after build_H in the context of optdriver 66.
1807 [ + - ]: 8 : if(dtset%optdriver==66) then
1808 : :
1809 : : !Set up of the k-points and tables in the whole BZ
1810 : 8 : call Kmesh%init(Cryst,dtset%nkpt,dtset%kptns,dtset%kptopt,wrap_1zone=.false.)
1811 [ + + ]: 16 : call Kmesh%print([std_out], header="K-mesh for the wavefunctions")
1812 : 8 : call Qmesh%find_qmesh(Cryst,Kmesh)
1813 [ + + ]: 16 : call Qmesh%print([std_out], header="Q-mesh for the screening function")
1814 : :
1815 : : !------------------------------
1816 : : !Building the vc_sqrt structure
1817 : : !------------------------------
1818 : : ! The sqrt_vc code relies on a different parallelism scheme than Vanilla ABINIT.
1819 : : ! The Gsphere object must be built on a single processor having all the G-vectors
1820 : : ! available.
1821 : :
1822 : : !gsph_init need gvec built according to the KSS convention, so that kg_k is not suitable (not properly sorted).
1823 : 8 : npw_serial=npw_k
1824 : 8 : call xmpi_sum(npw_serial,mpi_enreg%comm_bandfft,ierr)
1825 : :
1826 : 8 : ecut_eff = dtset%ecut*(dtset%dilatmx)**2
1827 : : call make_gvec_kss(dtset%nkpt,dtset%kptns,ecut_eff,dtset%symmorphi,dtset%nsym,dtset%symrel,dtset%tnons,Cryst%gprimd,&
1828 : 8 : dtset%prtvol,npw_serial,gvec,ierr)
1829 : :
1830 [ - + ]: 8 : call Gsphere%init(Cryst,npw_serial,gvec=gvec)
1831 [ + + ]: 16 : call Gsphere%print([std_out], 0)
1832 : :
1833 : : call Vcp%init(Gsphere,Cryst,Qmesh,Kmesh,dtset%gw_rcut,dtset%gw_icutcoul,dtset%vcutgeo,npw_serial,&
1834 : 8 : dtset%nkpt,dtset%kptns,mpi_enreg%comm_world)
1835 : :
1836 : : ! Since Vcp%vc_sqrt is sorted according to the KSS convention for G vectors
1837 : : ! BUT will be applied to GS wavefunctions (where G vectors are sorted otherwise)
1838 : : ! It is necessary to construct a vc_sqrt vector with the GS sorting.
1839 : : ! Moreover, if we are in parallel (over band / FFTs), Vcp%vc_sqrt is the serial version
1840 : : ! and need to be distributed according to the GS scheme (Linear Algebra configuration).
1841 [ - + + - : 24 : ABI_MALLOC(vc_sqrt,(npw_k))
+ - + - -
+ - + -
+ ]
1842 [ + + ]: 1293 : vc_sqrt=zero
1843 : 8 : k=0
1844 [ + + ]: 1301 : do i=1,npw_k
1845 [ + + ]: 331530 : do j=1,npw_serial
1846 [ + + + + : 390865 : if(all(kg_k(:,i)==gvec(:,j))) k=j
+ + ]
1847 : : end do
1848 : 1293 : vc_sqrt(i)=Vcp%vc_sqrt(k,1)
1849 : : end do
1850 : : end if
1851 : :
1852 : : !--------------------------------------------------------------------------------
1853 : : ! Security check : The eigenstates of the projector and the hamiltonian need to
1854 : : ! agree down to the precision requested (tolwfr). Otherwise, SQMR is doomed.
1855 : : ! Now that the density is read and the eigenstates are calculated in the GW run,
1856 : : ! it is less useful. A test on tolwfr could be sufficient.
1857 : : !
1858 : : ! This remains a good tool to debug band+fft parallelism
1859 : : !--------------------------------------------------------------------------------
1860 : :
1861 : : ! only write on the head node!
1862 [ + + ]: 8 : if (mpi_enreg%me == 0) then
1863 : 5 : io_unit = get_unit()
1864 : 5 : open(file='build_H.log',status=files_status_old,unit=io_unit)
1865 : 5 : write(io_unit,10) '#----------------------------------------------------------------------------'
1866 : 5 : write(io_unit,10) '#'
1867 : 5 : write(io_unit,10) '# This file presents the results of a small test to check '
1868 : 5 : write(io_unit,10) '# how well the Hamiltonian commutes with the projection '
1869 : 5 : write(io_unit,10) '# operator. '
1870 : 5 : write(io_unit,10) '#'
1871 : 5 : write(io_unit,10) '# Definitions:'
1872 : 5 : write(io_unit,10) '#'
1873 : 5 : write(io_unit,10) '# P : projections on conduction states'
1874 : 5 : write(io_unit,10) '# H : Hamiltonian operator'
1875 : 5 : write(io_unit,10) '# | psi > : eigenstate'
1876 : 5 : write(io_unit,10) '#'
1877 : 5 : flush(io_unit)
1878 : : end if
1879 : :
1880 [ + + + + ]: 4634 : psikb1 = zero
1881 : :
1882 : : ! sum all valence states, on copy in every band block.
1883 [ + + ]: 40 : do i=1,nbandv
1884 : :
1885 [ + + ]: 88 : do mb = 1, blocksize
1886 : :
1887 [ + + + + ]: 18584 : psikb1(:,(mb-1)*npw_k+1:mb*npw_k) = psikb1(:,(mb-1)*npw_k+1:mb*npw_k) + cg(:,(i-1)*npw_k+1:i*npw_k)
1888 : :
1889 : : end do
1890 : :
1891 : : end do
1892 : :
1893 : : ! normalize to one! Only sum the fist band block
1894 : 8 : tmpc = cg_zdotc(npw_k,psikb1,psikb1)
1895 : 8 : call xmpi_sum(tmpc,mpi_communicator ,ierr) ! sum on all processors
1896 [ + + + + ]: 4634 : psikb1 = psikb1/sqrt(tmpc(1))
1897 : :
1898 : :
1899 : : ! change data distribution
1900 : 8 : call wf_block_distribute(psikb1, psig1,1) ! LA -> FFT
1901 : :
1902 : : ! Apply P.H operator
1903 : 8 : call Hpsik(psig2 ,psig1)
1904 : 8 : call pc_k_valence_kernel(psig2)
1905 : :
1906 : : ! Apply H.P operator
1907 : 8 : call pc_k_valence_kernel(psig1)
1908 : 8 : call Hpsik(psig1)
1909 : :
1910 : : ! compute error
1911 [ + - + - : 4642 : psig3 = psig1 - psig2 ! explicitly write the difference in an array
- + - - +
+ + + ]
1912 : 8 : tmpc = cg_zdotc(npw_g,psig3,psig3)
1913 : 8 : commutation_error = tmpc(1)
1914 : :
1915 : 8 : call xmpi_sum(commutation_error , mpi_enreg%comm_fft, ierr) ! sum on all processors working on FFT!
1916 : :
1917 : : ! only write on the head node!
1918 [ + + ]: 8 : if (mpi_enreg%me == 0) then
1919 : 5 : write(io_unit,20) ' || (PH -HP) |b> ||^2 = ',commutation_error
1920 : 5 : write(io_unit,20) ' tolwfr = ',tolwfr
1921 : : end if
1922 : :
1923 [ - + ]: 8 : if(commutation_error > tolwfr) then
1924 : : !write(io_unit,10) '# || (PH -HP) |b> ||^2 > tolwfr ==> Decision taken exit!'
1925 : :
1926 [ # # ]: 0 : if (mpi_enreg%me == 0) write(io_unit,10) '# || (PH -HP) |b> ||^2 > tolwfr ==> This must be fixed!'
1927 : :
1928 : 0 : write(std_out,20) "WARNING-build_H: The tolerance tolwfr=",tolwfr
1929 : 0 : write(std_out,20) " is smaller than the commutation error ||(PH-HP)|b>||^2=",commutation_error
1930 : 0 : write(std_out,10) " Either set tolwfr to a less stringent value in this calculation"
1931 : 0 : write(std_out,10) " or to a more stringent value in the wavefunction calculation."
1932 : : end if
1933 : :
1934 [ + + ]: 8 : if (mpi_enreg%me == 0) close(io_unit)
1935 : :
1936 : : 10 format(A)
1937 : : 20 format(A,ES12.3)
1938 : 8 : end subroutine build_H
1939 : : !!***
1940 : :
1941 : : end module m_gwls_hamiltonian
1942 : : !!***
|