Line data Source code
1 : !!****m* ABINIT/m_gwls_polarisability
2 : !! NAME
3 : !! m_gwls_polarisability
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_polarisability
24 : ! local modules
25 : use m_gwls_utility
26 : use m_gwls_wf
27 : use m_gwls_valenceWavefunctions
28 : use m_gwls_hamiltonian
29 : use m_gwls_lineqsolver
30 :
31 : ! abinit modules
32 : use defs_basis
33 : use m_errors
34 : use m_abicore
35 : use m_bandfft_kpt
36 :
37 : use m_time, only : timab
38 :
39 : implicit none
40 : save
41 : private
42 : !!***
43 :
44 : real(dp),public :: matrix_function_omega(2)
45 :
46 :
47 : ! Some timing variables
48 : integer, public :: counter_fft = 0, counter_sqmr = 0, counter_rprod = 0 , counter_proj = 0, counter_H = 0
49 :
50 : real(dp), public :: time1 = zero, time2 = zero, time_fft = zero
51 : real(dp), public :: time_sqmr = zero, time_rprod = zero, time_proj = zero, time_H = zero
52 :
53 : real(dp), allocatable, public :: Sternheimer_solutions_zero(:,:,:,:)
54 : integer, public :: index_solution=0
55 : integer, public :: recy_unit
56 : logical, public :: write_solution=.false.
57 :
58 : !integer :: io_unit
59 : !!***
60 :
61 : public :: Pk, epsilon_k
62 : public :: matrix_function_epsilon_k
63 : public :: set_dielectric_function_frequency
64 : !!***
65 :
66 : contains
67 :
68 : !!****f* m_hamiltonian/Pk
69 : !! NAME
70 : !! Pk
71 : !!
72 : !! FUNCTION
73 : !! .
74 : !!
75 : !! INPUTS
76 : !!
77 : !! OUTPUT
78 : !!
79 : !! SOURCE
80 :
81 184 : subroutine Pk(psi_inout,omega)
82 : !===============================================================================
83 : !
84 : ! This routine applies the polarizability operator to an arbitrary state psi_inout.
85 : !
86 : !
87 : ! A note about parallelism:
88 : ! -------------------------
89 : ! The input/output is in "linear algebra" configuration, which is to say
90 : ! that ALL processors have a fraction of the G-vectors for this state. Internally,
91 : ! this routine will parallelise over bands and FFT, thus using the "FFT"
92 : ! configuration of the data. For more information, see the lobpcgwf.F90, and
93 : ! the article by F. Bottin et al.
94 : !===============================================================================
95 :
96 : real(dp), intent(inout) :: psi_inout(2,npw_k)
97 : real(dp), intent(in) :: omega(2)
98 :
99 : logical :: omega_imaginary
100 :
101 : integer :: v, mb, iblk
102 :
103 : real(dp):: norm_omega
104 184 : real(dp), allocatable :: psik(:,:)
105 184 : real(dp), allocatable :: psik_alltoall(:,:), psik_wrk_alltoall(:,:)
106 184 : real(dp), allocatable :: psik_in_alltoall(:,:), psik_tmp_alltoall(:,:)
107 :
108 184 : real(dp), allocatable :: psik_ext(:,:), psik_ext_alltoall(:,:)
109 :
110 :
111 184 : real(dp), allocatable :: psir(:,:,:,:), psir_ext(:,:,:,:)
112 :
113 : integer :: cplex
114 : integer :: recy_i
115 :
116 :
117 : integer :: mpi_band_rank
118 :
119 : real(dp) :: list_SQMR_frequencies(2)
120 : real(dp) :: list_QMR_frequencies(2,2)
121 :
122 :
123 : integer, save :: icounter = 0
124 : real(dp), save :: total_time1 = zero, total_time2 = zero, total_time = zero
125 :
126 :
127 : integer :: num_op_v, i_op_v, case_op_v
128 : real(dp):: factor_op_v
129 : real(dp):: lbda
130 : real(dp):: zz(2)
131 :
132 : character(len=500) :: message
133 :
134 : real(dp) :: tsec(2)
135 : integer :: GWLS_TIMAB, OPTION_TIMAB
136 :
137 : ! *************************************************************************
138 :
139 184 : GWLS_TIMAB = 1524
140 184 : OPTION_TIMAB = 1
141 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
142 :
143 :
144 :
145 184 : icounter = icounter + 1
146 184 : call cpu_time(total_time1)
147 :
148 :
149 : !========================================
150 : ! Allocate work arrays and define
151 : ! important parameters
152 : !========================================
153 184 : GWLS_TIMAB = 1525
154 : OPTION_TIMAB = 1
155 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
156 :
157 :
158 184 : cplex = 2 ! complex potential
159 :
160 184 : mpi_band_rank = mpi_enreg%me_band
161 :
162 552 : ABI_MALLOC(psik, (2,npw_kb))
163 552 : ABI_MALLOC(psik_alltoall, (2,npw_g))
164 368 : ABI_MALLOC(psik_wrk_alltoall, (2,npw_g))
165 368 : ABI_MALLOC(psik_tmp_alltoall, (2,npw_g))
166 368 : ABI_MALLOC(psik_in_alltoall, (2,npw_g))
167 :
168 920 : ABI_MALLOC(psir, (2,n4,n5,n6))
169 736 : ABI_MALLOC(psir_ext,(2,n4,n5,n6))
170 :
171 :
172 184 : OPTION_TIMAB = 2
173 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
174 :
175 :
176 : !--------------------------------------------------------------------------------
177 : !
178 : ! The polarizability acting on a state | PSI > is given by
179 : !
180 : ! Pk | PSI > = 2 sum_{v} | h_v^* phi_v > ( factor of 2 comes from sum on spin)
181 : !
182 : ! | h_v > = Pc . OPERATOR_v . Pc | PSI^* phi_v >
183 : !
184 : ! There are multiple cases to consider:
185 : !
186 : ! CASE:
187 : ! 1) |omega| = 0
188 : ! OPERATOR_v = 1/[H-ev]
189 : ! prefactor = -4
190 : !
191 : ! 2) omega = i lbda (imaginary)
192 : ! OPERATOR_v = [H-ev]/(lbda^2+[H-ev]^2)
193 : ! prefactor = -4
194 : !
195 : ! 3) omega = lbda (real) (USE SQMR)
196 : ! OPERATOR_v = { 1/[H-ev+lbda]+ 1/[H-ev-lbda] }
197 : ! prefactor = -2
198 : !
199 : ! 4) omega = lbda (real) (USE QMR)
200 : ! OPERATOR_v = { 1/[H-ev+lbda]+ 1/[H-ev-lbda] }
201 : ! prefactor = -2
202 : !
203 : ! It simplifies the code below to systematize the algorithm.
204 : !
205 : !--------------------------------------------------------------------------------
206 :
207 : ! Check which part of omega is non-zero. Default is that omega is real.
208 184 : if (abs(omega(2)) < 1.0d-12) then
209 184 : omega_imaginary=.false.
210 184 : norm_omega = omega(1)
211 :
212 0 : elseif (abs(omega(1)) < 1.0d-12 .and. abs(omega(2)) > 1.0d-12) then
213 0 : omega_imaginary = .true.
214 0 : norm_omega = omega(2)
215 :
216 : else
217 : write(message,"(a,es16.8,3a)")&
218 0 : "omega=",omega,",",ch10,&
219 0 : "but either it's real or imaginary part need to be 0 for the polarisability routine to work."
220 0 : ABI_ERROR(message)
221 : end if
222 :
223 :
224 : !-----------------------------------------------------------------
225 : ! I) Prepare global values depending on the CASE being considered
226 : !-----------------------------------------------------------------
227 :
228 184 : if (norm_omega < 1.0D-12 ) then
229 72 : case_op_v = 1
230 72 : num_op_v = 1
231 72 : factor_op_v = -4.0_dp
232 :
233 112 : else if (omega_imaginary) then
234 0 : case_op_v = 2
235 0 : num_op_v = 1
236 0 : factor_op_v = -4.0_dp
237 :
238 112 : else if( .not. activate_inf_shift_poles) then
239 96 : case_op_v = 3
240 96 : num_op_v = 2
241 96 : factor_op_v = -2.0_dp
242 :
243 : else
244 16 : case_op_v = 4
245 16 : num_op_v = 2
246 16 : factor_op_v = -2.0_dp
247 :
248 16 : inf_shift_poles = dtset%zcut
249 :
250 :
251 16 : write(message,*) " inf_shift_poles = ",inf_shift_poles
252 16 : call wrtout(std_out,message,'COLL')
253 : end if
254 :
255 :
256 184 : write(message,10)" "
257 184 : call wrtout(std_out,message,'COLL')
258 184 : write(message,10) " Pk: applying the polarizability on states"
259 184 : call wrtout(std_out,message,'COLL')
260 184 : write(message,10) " =============================================================="
261 184 : call wrtout(std_out,message,'COLL')
262 184 : write(message,12) " CASE : ",case_op_v
263 184 : call wrtout(std_out,message,'COLL')
264 :
265 :
266 :
267 : !-----------------------------------------------------------------
268 : ! II) copy conjugate of initial wavefunction in local array,
269 : ! and set inout array to zero. Each FFT row of processors
270 : ! must have a copy of the initial wavefunction in FFT
271 : ! configuration!
272 : !-----------------------------------------------------------------
273 184 : call cpu_time(time1)
274 :
275 184 : GWLS_TIMAB = 1526
276 184 : OPTION_TIMAB = 1
277 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
278 :
279 :
280 552 : ABI_MALLOC(psik_ext,(2,npw_kb))
281 552 : ABI_MALLOC(psik_ext_alltoall,(2,npw_g))
282 :
283 : ! fill the array psik_ext with copies of the external state
284 464 : do mb = 1, blocksize
285 105320 : psik_ext(:,(mb-1)*npw_k+1:mb*npw_k) = psi_inout(:,:)
286 : end do
287 :
288 : ! change configuration of the data, from LA to FFT
289 184 : call wf_block_distribute(psik_ext, psik_ext_alltoall,1) ! LA -> FFT
290 : ! Now every row of FFT processors has a copy of the external state.
291 :
292 : ! Copy the external state to the real space format, appropriate for real space products to be
293 : ! used later.
294 :
295 184 : call g_to_r(psir_ext,psik_ext_alltoall)
296 1262056 : psir_ext(2,:,:,:) = -psir_ext(2,:,:,:)
297 :
298 :
299 : ! Don't need these arrays anymore...
300 184 : ABI_FREE(psik_ext)
301 184 : ABI_FREE(psik_ext_alltoall)
302 :
303 184 : OPTION_TIMAB = 2
304 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
305 :
306 184 : call cpu_time(time2)
307 184 : time_fft = time_fft + time2-time1
308 184 : counter_fft = counter_fft+1
309 :
310 : ! set external state to zero, ready to start cumulating the answer
311 86536 : psi_inout = zero
312 :
313 : !-----------------------------------------------------------------
314 : ! III) Iterate on all valence bands
315 : !-----------------------------------------------------------------
316 :
317 : ! Loop on all blocks of eigenstates
318 1544 : do iblk = 1, nbdblock
319 :
320 :
321 : ! What is the valence band index for this block and this row of FFT processors? It is not clear from the
322 : ! code in lobpcgwf.F90; I'm going to *guess*.
323 :
324 1360 : v = (iblk-1)*blocksize + mpi_band_rank + 1 ! CAREFUL! This is a guess. Revisit this if code doesn't work as intended.
325 :
326 :
327 : !Solving of Sternheiner equation
328 1360 : write(message,12) " band :", v
329 1360 : call wrtout(std_out,message,'COLL')
330 1360 : write(message,14) " eigenvalue (Ha) : ",eig(v)
331 1360 : call wrtout(std_out,message,'COLL')
332 1360 : write(message,14) " Re[omega] (Ha) : ",omega(1)
333 1360 : call wrtout(std_out,message,'COLL')
334 1360 : write(message,14) " Im[omega] (Ha) : ",omega(2)
335 1360 : call wrtout(std_out,message,'COLL')
336 :
337 : !-----------------------------------------------------------------
338 : ! IV) prepare some arrays, if they are needed
339 : !-----------------------------------------------------------------
340 1360 : if (case_op_v == 3) then
341 :
342 640 : list_SQMR_frequencies(1) = eig(v) - norm_omega
343 640 : list_SQMR_frequencies(2) = eig(v) + norm_omega
344 :
345 720 : else if (case_op_v == 4) then
346 480 : list_QMR_frequencies(:,1) = (/eig(v)-norm_omega,-inf_shift_poles/)
347 480 : list_QMR_frequencies(:,2) = (/eig(v)+norm_omega, inf_shift_poles/)
348 : end if
349 :
350 :
351 : !-----------------------------------------------------------------
352 : ! V) Compute the real-space product of the input wavefunction
353 : ! with the valence wavefunction.
354 : !-----------------------------------------------------------------
355 : ! Unfortunately, the input wavefunctions will be FFT-transformed k-> r nbandv times
356 : ! because fourwf cannot multiply a real-space potential with a real-space wavefunction!
357 1360 : call cpu_time(time1)
358 :
359 1360 : GWLS_TIMAB = 1527
360 1360 : OPTION_TIMAB = 1
361 1360 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
362 :
363 1360 : call gr_to_g(psik_in_alltoall,psir_ext,valence_wavefunctions_FFT(:,:,iblk))
364 :
365 1360 : OPTION_TIMAB = 2
366 1360 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
367 :
368 :
369 1360 : call cpu_time(time2)
370 1360 : time_fft = time_fft + time2-time1
371 1360 : counter_fft = counter_fft+1
372 :
373 : !-----------------------------------------------------------------
374 : ! VI) Project out to conduction space
375 : !-----------------------------------------------------------------
376 1360 : call cpu_time(time1)
377 :
378 1360 : GWLS_TIMAB = 1528
379 1360 : OPTION_TIMAB = 1
380 1360 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
381 :
382 : !call pc_k(psik_in)
383 1360 : call pc_k_valence_kernel(psik_in_alltoall)
384 :
385 1360 : OPTION_TIMAB = 2
386 1360 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
387 :
388 1360 : call cpu_time(time2)
389 1360 : time_proj = time_proj + time2-time1
390 1360 : counter_proj= counter_proj+1
391 :
392 :
393 : !-----------------------------------------------------------------
394 : ! VII) Loop on potential valence operators,
395 : !-----------------------------------------------------------------
396 3704 : do i_op_v = 1, num_op_v
397 :
398 2160 : if (case_op_v == 1) then
399 :
400 : ! frequency is zero, operator to apply is 1/[H-ev]
401 560 : call cpu_time(time1)
402 560 : GWLS_TIMAB = 1529
403 560 : OPTION_TIMAB = 1
404 560 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
405 :
406 560 : call sqmr(psik_in_alltoall,psik_tmp_alltoall,eig(v),1)
407 :
408 560 : OPTION_TIMAB = 2
409 560 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
410 :
411 :
412 560 : call cpu_time(time2)
413 560 : time_sqmr = time_sqmr+ time2-time1
414 560 : counter_sqmr= counter_sqmr+1
415 :
416 : ! If we are constructing the $\hat \epsilon(i\omega = 0)$ matrix (and the Lanczos basis at the same time),
417 : ! keep the Sternheimer solutions for use in the projected Sternheimer section (in LA configuration).
418 560 : if(write_solution .and. ((iblk-1)*blocksize < nbandv)) then
419 160 : call wf_block_distribute(psik, psik_tmp_alltoall, 2) ! FFT -> LA
420 384 : do mb=1,blocksize
421 224 : v = (iblk-1)*blocksize+mb
422 384 : if(v <= nbandv) then
423 224 : if(dtset%gwls_recycle == 1) then
424 24800 : Sternheimer_solutions_zero(:,:,index_solution,v) = psik(:,(mb-1)*npw_k+1:mb*npw_k)
425 : end if
426 224 : if(dtset%gwls_recycle == 2) then
427 96 : recy_i = (index_solution-1)*nbandv + v
428 : !BUG : On petrus, NAG 5.3.1 + OpenMPI 1.6.2 cause read(...,rec=i) to read the data written by write(...,rec=i+1).
429 : !Workaround compatible only with nag : write(recy_unit,rec=recy_i+1).
430 96 : write(recy_unit,rec=recy_i) psik(:,(mb-1)*npw_k+1:mb*npw_k)
431 : end if
432 : end if
433 : end do
434 : end if
435 :
436 1600 : else if (case_op_v == 2) then
437 :
438 : ! frequency purely imaginary, operator to apply is
439 : ! [H-ev]/(lbda^2+[H-ev]^2)
440 0 : call cpu_time(time1)
441 :
442 0 : GWLS_TIMAB = 1533
443 0 : OPTION_TIMAB = 1
444 0 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
445 :
446 0 : psik_wrk_alltoall = psik_in_alltoall
447 0 : call Hpsik(psik_wrk_alltoall,eig(v))
448 :
449 0 : OPTION_TIMAB = 2
450 0 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
451 :
452 :
453 0 : call cpu_time(time2)
454 0 : time_H = time_H + time2-time1
455 0 : counter_H = counter_H+1
456 :
457 0 : call cpu_time(time1)
458 :
459 0 : GWLS_TIMAB = 1530
460 0 : OPTION_TIMAB = 1
461 0 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
462 :
463 0 : call sqmr(psik_wrk_alltoall,psik_tmp_alltoall,eig(v),0,norm_omega,omega_imaginary)
464 :
465 0 : OPTION_TIMAB = 2
466 0 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
467 :
468 :
469 0 : call cpu_time(time2)
470 0 : time_sqmr = time_sqmr+ time2-time1
471 0 : counter_sqmr= counter_sqmr+1
472 :
473 1600 : else if (case_op_v == 3) then
474 :
475 : ! frequency purely real, operator to apply is
476 : ! 1/[H-ev +/- lbda]
477 : ! TREATED WITH SQMR
478 :
479 :
480 1280 : lbda = list_SQMR_frequencies(i_op_v)
481 1280 : call cpu_time(time1)
482 :
483 1280 : GWLS_TIMAB = 1531
484 1280 : OPTION_TIMAB = 1
485 1280 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
486 :
487 1280 : call sqmr(psik_in_alltoall,psik_tmp_alltoall,lbda,1)
488 :
489 1280 : OPTION_TIMAB = 2
490 1280 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
491 :
492 :
493 :
494 1280 : call cpu_time(time2)
495 1280 : time_sqmr = time_sqmr+ time2-time1
496 1280 : counter_sqmr= counter_sqmr+1
497 :
498 320 : else if (case_op_v == 4) then
499 : ! frequency purely real, operator to apply is
500 : ! 1/[H-ev +/- lbda]
501 : ! TREATED WITH QMR
502 :
503 960 : zz(:) = list_QMR_frequencies(:,i_op_v)
504 :
505 320 : call cpu_time(time1)
506 320 : GWLS_TIMAB = 1532
507 320 : OPTION_TIMAB = 1
508 320 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
509 :
510 320 : call qmr(psik_in_alltoall,psik_tmp_alltoall,zz) !,0)
511 :
512 320 : OPTION_TIMAB = 2
513 320 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
514 :
515 :
516 320 : call cpu_time(time2)
517 320 : time_sqmr = time_sqmr+ time2-time1
518 320 : counter_sqmr= counter_sqmr+1
519 :
520 : end if
521 : !-----------------------------------------------------------------
522 : ! VIII) Project on conduction states
523 : !-----------------------------------------------------------------
524 2160 : call cpu_time(time1)
525 2160 : GWLS_TIMAB = 1528
526 2160 : OPTION_TIMAB = 1
527 2160 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
528 :
529 2160 : call pc_k_valence_kernel(psik_tmp_alltoall)
530 :
531 2160 : OPTION_TIMAB = 2
532 2160 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
533 :
534 :
535 2160 : call cpu_time(time2)
536 2160 : time_proj = time_proj + time2-time1
537 2160 : counter_proj= counter_proj+1
538 :
539 : !-----------------------------------------------------------------
540 : ! IX) Conjugate result, and express in denpot format
541 : !-----------------------------------------------------------------
542 :
543 2160 : call cpu_time(time1)
544 :
545 2160 : GWLS_TIMAB = 1526
546 2160 : OPTION_TIMAB = 1
547 2160 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
548 :
549 :
550 2160 : call g_to_r(psir,psik_tmp_alltoall)
551 14815440 : psir(2,:,:,:) = -psir(2,:,:,:)
552 :
553 :
554 2160 : OPTION_TIMAB = 2
555 2160 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
556 :
557 2160 : call cpu_time(time2)
558 2160 : time_fft = time_fft + time2-time1
559 2160 : counter_fft = counter_fft+1
560 :
561 : !-----------------------------------------------------------------
562 : ! X) Multiply by valence state in real space
563 : !-----------------------------------------------------------------
564 2160 : call cpu_time(time1)
565 2160 : GWLS_TIMAB = 1527
566 2160 : OPTION_TIMAB = 1
567 2160 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
568 :
569 2160 : call gr_to_g(psik_alltoall,psir,valence_wavefunctions_FFT(:,:,iblk))
570 :
571 :
572 2160 : OPTION_TIMAB = 2
573 2160 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
574 :
575 :
576 2160 : call cpu_time(time2)
577 2160 : time_fft = time_fft + time2-time1
578 2160 : counter_fft = counter_fft+1
579 :
580 : !-----------------------------------------------------------------
581 : ! XI) Return to LA configuration, and cumulate the sum
582 : !-----------------------------------------------------------------
583 2160 : call wf_block_distribute(psik, psik_alltoall,2) ! FFT -> LA
584 :
585 6480 : do mb = 1, blocksize
586 :
587 2960 : v = (iblk-1)*blocksize + mb
588 :
589 5120 : if (v <= nbandv) then
590 : ! only add contributions from valence
591 543968 : psi_inout(:,:) = psi_inout(:,:) + psik(:,(mb-1)*npw_k+1:mb*npw_k)
592 : end if
593 :
594 : end do
595 :
596 :
597 : end do ! i_op_v
598 :
599 : end do ! iblk
600 :
601 :
602 : !-----------------------------------------------------------------
603 : ! XII) account for prefactor
604 : !-----------------------------------------------------------------
605 86536 : psi_inout = factor_op_v*psi_inout
606 :
607 :
608 184 : GWLS_TIMAB = 1525
609 184 : OPTION_TIMAB = 1
610 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
611 :
612 :
613 184 : ABI_FREE(psik)
614 184 : ABI_FREE(psik_alltoall)
615 184 : ABI_FREE(psik_wrk_alltoall)
616 184 : ABI_FREE(psik_tmp_alltoall)
617 184 : ABI_FREE(psik_in_alltoall)
618 :
619 184 : ABI_FREE(psir)
620 184 : ABI_FREE(psir_ext)
621 :
622 184 : OPTION_TIMAB = 2
623 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
624 :
625 :
626 184 : call cpu_time(total_time2)
627 :
628 184 : total_time = total_time + total_time2 - total_time1
629 :
630 :
631 184 : GWLS_TIMAB = 1524
632 : OPTION_TIMAB = 2
633 184 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
634 :
635 : 10 format(A)
636 : 12 format(A,I5)
637 : 14 format(A,F24.16)
638 :
639 184 : end subroutine Pk
640 : !!***
641 :
642 : !!****f* m_hamiltonian/epsilon_k
643 : !! NAME
644 : !! epsilon_k
645 : !!
646 : !! FUNCTION
647 : !! .
648 : !!
649 : !! INPUTS
650 : !!
651 : !! OUTPUT
652 : !!
653 : !! SOURCE
654 :
655 184 : subroutine epsilon_k(psi_out,psi_in,omega)
656 :
657 : real(dp), intent(out) :: psi_out(2,npw_k)
658 : real(dp), intent(in) :: psi_in(2,npw_k), omega(2)
659 :
660 : ! *************************************************************************
661 :
662 86536 : psi_out = psi_in
663 184 : call sqrt_vc_k(psi_out)
664 184 : call Pk(psi_out,omega)
665 184 : call sqrt_vc_k(psi_out)
666 :
667 86536 : psi_out = psi_in - psi_out
668 184 : end subroutine epsilon_k
669 : !!***
670 :
671 : !!****f* m_hamiltonian/set_dielectric_function_frequency
672 : !! NAME
673 : !! set_dielectric_function_frequency
674 : !!
675 : !! FUNCTION
676 : !! .
677 : !!
678 : !! INPUTS
679 : !!
680 : !! OUTPUT
681 : !!
682 : !! SOURCE
683 :
684 22 : subroutine set_dielectric_function_frequency(omega)
685 : !----------------------------------------------------------------------------------------------------
686 : ! This routine sets the value of the module's frequency.
687 : !----------------------------------------------------------------------------------------------------
688 : real(dp), intent(in) :: omega(2)
689 :
690 : ! *************************************************************************
691 :
692 22 : matrix_function_omega(:) = omega(:)
693 :
694 22 : end subroutine set_dielectric_function_frequency
695 : !!***
696 :
697 : !!****f* m_hamiltonian/matrix_function_epsilon_k
698 : !! NAME
699 : !! matrix_function_epsilon_k
700 : !!
701 : !! FUNCTION
702 : !! .
703 : !!
704 : !! INPUTS
705 : !!
706 : !! OUTPUT
707 : !!
708 : !! SOURCE
709 :
710 184 : subroutine matrix_function_epsilon_k(vector_out,vector_in,Hsize)
711 : !----------------------------------------------------------------------------------------------------
712 : ! This function is a simple wrapper around epsilon_k to be fed to the Lanczos
713 : ! algorithm.
714 : !----------------------------------------------------------------------------------------------------
715 : integer, intent(in) :: Hsize
716 : complex(dp), intent(out) :: vector_out(Hsize)
717 : complex(dp), intent(in) :: vector_in(Hsize)
718 :
719 :
720 : ! local variables
721 368 : real(dp) :: psik (2,npw_k)
722 184 : real(dp) :: psik2(2,npw_k)
723 :
724 : ! *************************************************************************
725 :
726 : ! convert from one format to the other
727 28968 : psik(1,:) = dble (vector_in(:))
728 28968 : psik(2,:) = dimag(vector_in(:))
729 :
730 : ! act on vector
731 :
732 :
733 184 : call epsilon_k(psik2 ,psik, matrix_function_omega)
734 :
735 : ! convert back
736 28968 : vector_out = cmplx_1*psik2(1,:)+cmplx_i*psik2(2,:)
737 :
738 184 : end subroutine matrix_function_epsilon_k
739 : !!***
740 :
741 : end module m_gwls_polarisability
742 : !!***
|