~ubuntu-branches/debian/stretch/abinit/stretch

« back to all changes in this revision

Viewing changes to src/17suscep/suscep.F90

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme
  • Date: 2007-09-14 13:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20070914130500-1kzh2mrgo6ir4b6i
Tags: upstream-5.3.4.dfsg
ImportĀ upstreamĀ versionĀ 5.3.4.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
!{\src2tex{textfont=tt}}
 
2
!!****f* ABINIT/suscep
 
3
!! NAME
 
4
!! suscep
 
5
!!
 
6
!! FUNCTION
 
7
!! Primary routine for conducting DFT calculations of the polarisability
 
8
!! within the random phase approximation (RPA)
 
9
!!
 
10
!! COPYRIGHT
 
11
!! Copyright (C) 2000-2007 ABINIT group (XG,GMR,MF)
 
12
!! This file is distributed under the terms of the
 
13
!! GNU General Public License, see ~abinit/COPYING
 
14
!! or http://www.gnu.org/copyleft/gpl.txt .
 
15
!! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
 
16
!!
 
17
!! INPUTS
 
18
!!  dtfil <type(datafiles_type)>=variables related to files
 
19
!!  dtset <type(dataset_type)>=all input variables in this dataset
 
20
!!  mband =maximum number of bands
 
21
!!  mgfft =maximum single fft dimension
 
22
!!  mpi_enreg=informations about MPI parallelization
 
23
!!  mpw   =maximum number of planewaves in basis sphere (large number)
 
24
!!  natom =number of atoms in unit cell
 
25
!!  nkpt  =number of k points
 
26
!!  nspden=number of spin-density components
 
27
!!  nspinor=number of spinorial components of the wavefunctions
 
28
!!  nsppol=number of channels for spin-polarization (1 or 2)
 
29
!!  nsym=number of symmetry elements in space group
 
30
!!  xred(3,natom)=reduced dimensionless atomic coordinates
 
31
!!
 
32
!! OUTPUT
 
33
!!  (no direct output : results written)
 
34
!!
 
35
!! SIDE EFFECTS
 
36
!!  mkmem =maximum number of k points which can fit in core memory
 
37
!!
 
38
!! PARENTS
 
39
!!      driver
 
40
!!
 
41
!! CHILDREN
 
42
!!      distrb2,getfreqsus,getmpw,getng,hdr_clean,inwffil3,ioarr,kpgio,metric
 
43
!!      mkrdim,newocc,setsym,sphereboundary,status,suscep_dyn,suscep_stat,timab
 
44
!!      wffclose,wrtout,xcacfd,xme_init
 
45
!!
 
46
!! SOURCE
 
47
 
 
48
#if defined HAVE_CONFIG_H
 
49
#include "config.h"
 
50
#endif
 
51
 
 
52
subroutine suscep(dtfil,dtset,iexit,&
 
53
& mband,mgfft,mkmem,mpi_enreg,mpw,natom,nfft,nkpt,&
 
54
& nspden,nspinor,nsppol,nsym,occ,xred,ncdims,ngfft)
 
55
 
 
56
 use defs_basis
 
57
 use defs_datatypes
 
58
 
 
59
!This section has been created automatically by the script Abilint (TD). Do not modify these by hand.
 
60
#ifdef HAVE_FORTRAN_INTERFACES
 
61
 use interfaces_01manage_mpi
 
62
 use interfaces_11util
 
63
 use interfaces_12ffts
 
64
 use interfaces_12geometry
 
65
 use interfaces_13io_mpi
 
66
 use interfaces_13recipspace
 
67
 use interfaces_14iowfdenpot
 
68
 use interfaces_14occeig
 
69
 use interfaces_17suscep, except_this_one => suscep
 
70
 use interfaces_lib01hidempi
 
71
#endif
 
72
!End of the abilint section
 
73
 
 
74
 implicit none
 
75
 
 
76
!Arguments ------------------------------------
 
77
!scalars
 
78
 integer,intent(in) :: iexit,mband,mgfft,mpw,natom,nfft,nkpt,nspden,nsppol,nsym
 
79
 integer,intent(inout) :: mkmem,nspinor
 
80
 type(MPI_type),intent(inout) :: mpi_enreg
 
81
 type(datafiles_type),intent(in) :: dtfil
 
82
 type(dataset_type),intent(in) :: dtset
 
83
 type(vardims_type),intent(inout) :: ncdims
 
84
!arrays
 
85
 integer,intent(in) :: ngfft(18)
 
86
 real(dp),intent(in) :: xred(3,natom)
 
87
 real(dp),intent(inout) :: occ(mband*nkpt*nsppol)
 
88
 
 
89
!Local variables-------------------------------
 
90
!scalars
 
91
 integer,parameter :: level=3
 
92
 integer :: accessfil,dielop,fformr,ierr,ifreq,ii,ipw1,ipw2,isp,isp1,isp2
 
93
 integer :: master,me,mgfftdiel,nband_mx,ncblocks,nfftdiel,nfreqsus,npwdiel
 
94
 integer :: prtvol,rdwr,rdwrpaw,susopt
 
95
 real(dp) :: diecut,dummy,ecutsus,entropy,etotal,fermie,residm,ucvol
 
96
 character(len=500) :: message
 
97
 character(len=fnlen) :: filkgs,filsustr,kgnam
 
98
 type(dens_sym_operator_type) :: densymop_diel
 
99
 type(hdr_type) :: hdr
 
100
 type(wffile_type) :: wff1
 
101
!arrays
 
102
 integer :: ngfftdiel(18),npwarr_diel(1),npwtot_diel(1)
 
103
 integer,allocatable :: gbound_diel(:,:),indsym(:,:,:),irrzondiel(:,:,:)
 
104
 integer,allocatable :: kg(:,:),kg_diel(:,:),nband_dum(:),npwarr(:),npwtot(:)
 
105
 integer,allocatable :: symrec(:,:,:)
 
106
 real(dp) :: dielar(7),gmet(3,3),gprimd(3,3),kpt_diel(3),rmet(3,3),rprimd(3,3)
 
107
 real(dp) :: tsec(2)
 
108
 real(dp),allocatable :: cg(:,:),dielinv(:,:,:,:,:),doccde(:),eigen(:),freq(:)
 
109
 real(dp),allocatable :: phnonsdiel(:,:,:),rhor(:,:),susd_non_dyn(:,:,:,:)
 
110
 real(dp),allocatable :: susmat(:,:,:,:,:),susmat_dyn(:,:,:,:,:,:),wght_freq(:)
 
111
 
 
112
!***********************************************************************
 
113
 
 
114
 call timab(84,1,tsec)
 
115
 call status(0,dtfil%filstat,iexit,level,'enter         ')
 
116
 
 
117
 mpi_enreg%paralbd=0
 
118
 mpi_enreg%me_fft=0
 
119
 mpi_enreg%nproc_fft=1
 
120
 mpi_enreg%paral_fft=0
 
121
 mpi_enreg%paral_level=2
 
122
 
 
123
!
 
124
!  If dtset%accesswff == 2 set all array outputs to netcdf format
 
125
!
 
126
 accessfil = 0
 
127
 if (dtset%accesswff == 2) then
 
128
   accessfil = 1
 
129
 end if
 
130
 if (dtset%accesswff == 3) then
 
131
   accessfil = 3
 
132
 end if
 
133
 
 
134
 master=0
 
135
!Init me
 
136
 call xme_init(mpi_enreg,me)
 
137
 
 
138
 if(mpi_enreg%paral_compil_kpt==1)then
 
139
  allocate(mpi_enreg%proc_distrb(nkpt,mband,nsppol))
 
140
  mpi_enreg%parareel=0
 
141
  call distrb2(mband, dtset%nband, nkpt, nsppol, mpi_enreg)
 
142
 end if
 
143
 
 
144
!Structured debugging if prtvol==-level
 
145
 prtvol=dtset%prtvol
 
146
 if(prtvol==-level)then
 
147
  write(message,'(80a,a,a)')  ('=',ii=1,80),ch10,&
 
148
&   ' suscep : enter , debug mode '
 
149
  call wrtout(06,message,'COLL')
 
150
 end if
 
151
 
 
152
!Loop input variables
 
153
 nfreqsus=dtset%nfreqsus
 
154
 
 
155
 dielar(1)=dtset%diecut
 
156
 dielar(2)=dtset%dielng
 
157
 dielar(3)=dtset%diemac
 
158
 dielar(4)=dtset%diemix
 
159
 dielar(5)=dtset%diegap
 
160
 dielar(6)=dtset%dielam
 
161
 
 
162
!Unit numbers and file name for the _KGS file
 
163
 filkgs=trim(dtfil%filnam_ds(5))//'_KGS'
 
164
 filsustr=trim(dtfil%filnam_ds(5))//'_SUSTR'
 
165
 
 
166
!Impose mkmem=0 to read cg from disk
 
167
 mkmem=0
 
168
 
 
169
 call status(0,dtfil%filstat,iexit,level,'call inwffil3 ')
 
170
 
 
171
!Compute different geometric tensor, as well as ucvol, from rprimd
 
172
 call mkrdim(dtset%acell_orig,dtset%rprim_orig,rprimd)
 
173
 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
 
174
 
 
175
!Get diecut, and the fft grid to be used for the susceptibility computation
 
176
 diecut=abs(dielar(1))
 
177
 if( dielar(1)<0.0_dp )then
 
178
  ecutsus= dtset%ecut
 
179
 else
 
180
  ecutsus= ( sqrt( dtset%ecut) *0.5_dp + sqrt(diecut) *0.25_dp )**2
 
181
 end if
 
182
 
 
183
 ngfftdiel(1:3)=0 ; ngfftdiel(7)=101 ; ngfftdiel(8:18)=dtset%ngfft(8:18)
 
184
 call getng(dtset%boxcutmin,ecutsus,gmet,mpi_enreg%me_fft,mgfftdiel,nfftdiel,ngfftdiel,&
 
185
& mpi_enreg%nproc_fft,nsym,mpi_enreg%fft_option_lob,mpi_enreg%paral_fft,dtset%symrel)
 
186
 
 
187
!Compute the size of the dielectric matrix
 
188
 kpt_diel(1:3)=(/ 0.0_dp, 0.0_dp, 0.0_dp /)
 
189
 call getmpw(diecut,dtset%exchn2n3,gmet,(/1/),kpt_diel,&
 
190
& mpi_enreg,npwdiel,1,ucvol)
 
191
 
 
192
!Now, performs allocation
 
193
 allocate(cg(2,mpw*nspinor*mband*mkmem*nsppol))
 
194
 allocate(eigen(mband*nkpt*nsppol))
 
195
 allocate(kg(3,mpw*mkmem))
 
196
 allocate(kg_diel(3,npwdiel))
 
197
 allocate(npwarr(nkpt),npwtot(nkpt))
 
198
 allocate(gbound_diel(2*mgfftdiel+8,2))
 
199
 allocate(irrzondiel(nfftdiel**(1-1/nsym),2,nspden/nsppol))
 
200
 allocate(phnonsdiel(2,nfftdiel**(1-1/nsym),nspden/nsppol))
 
201
 allocate(nband_dum(nsppol))
 
202
 
 
203
!Then, initialize and compute the values of different arrays
 
204
 call kpgio(dtset%ecut,dtset%exchn2n3,gmet,dtset%istwfk,kg,filkgs,dtset%kptns,mkmem,&
 
205
& dtset%nband,nkpt,'PERS',mpi_enreg,mpw,npwarr,npwtot,nsppol,dtfil%unkg)
 
206
!This kpgio call for going from the suscep FFT grid to the diel sphere
 
207
!Note : kgnam is dummy, npwarr_diel is dummy, npwtot_diel is dummy, nband_dum is dummy
 
208
 nband_dum(:) = 1
 
209
 call kpgio(diecut,dtset%exchn2n3,gmet,(/1/),kg_diel,kgnam,&
 
210
& kpt_diel,1,nband_dum,1,'COLL',mpi_enreg,npwdiel,npwarr_diel,npwtot_diel,&
 
211
& nsppol,tmp_unit)
 
212
 
 
213
 call sphereboundary(gbound_diel,1,kg_diel,mgfftdiel,npwdiel)
 
214
 
 
215
 allocate(indsym(4,nsym,natom),symrec(3,3,nsym))
 
216
 if (nsym>1) then
 
217
  call setsym(densymop_diel,indsym,irrzondiel,dtset%iscf,natom,&
 
218
&  nfftdiel,ngfftdiel,nspden,nsppol,nsym,phnonsdiel,&
 
219
&  dtset%symafm,symrec,dtset%symrel,dtset%tnons,dtset%typat,xred)
 
220
 end if
 
221
 
 
222
!Read eigenvalues from the wavefunction file
 
223
!Also, initialize wff1 and hdr
 
224
 eigen(:)=0.0_dp
 
225
! mpi_enreg%paralbd=0
 
226
 call inwffil3(dtset,eigen,hdr,dtset%istwfk,mband,mpi_enreg,dtset%nband,&
 
227
& nkpt,npwarr,nsppol,prtvol,wff1,dtfil%unwff1,dtfil%fnamewffk)
 
228
 
 
229
!Compute new occupation numbers if needed
 
230
 allocate(doccde(mband*nkpt*nsppol))
 
231
 if(dtset%occopt>=3.and.dtset%occopt<=7) then
 
232
  call status(0,dtfil%filstat,iexit,level,'call newocc   ')
 
233
  call newocc(doccde,eigen,entropy,fermie,dtset%fixmom,mband,dtset%nband,&
 
234
&  dtset%nelect,nkpt,nspinor,nsppol,occ,dtset%occopt,prtvol,dtset%stmbias,&
 
235
&  dtset%tphysel,dtset%tsmear,dtset%wtk)
 
236
 end if
 
237
 
 
238
 dielop=2 ! Immediate computation of dielectric matrix
 
239
 if(nfreqsus==0) then
 
240
 
 
241
! Perform allocations
 
242
  allocate(dielinv(2,npwdiel,nspden,npwdiel,nspden))
 
243
  allocate(susmat(2,npwdiel,nspden,npwdiel,nspden))
 
244
  susmat(:,:,:,:,:)=0._dp
 
245
 
 
246
! Compute the static susceptibility matrix
 
247
  call suscep_stat(cg,densymop_diel,&
 
248
&  dielar,dielop,doccde,eigen,gbound_diel,&
 
249
&  irrzondiel,dtset%istwfk,kg,kg_diel,&
 
250
&  mband,mgfftdiel,mkmem,mpi_enreg,mpw,dtset%nband,nfftdiel,ngfftdiel,&
 
251
&  nkpt,npwarr,npwdiel,nspden,nspinor,nsppol,nsym,&
 
252
&  occ,dtset%occopt,phnonsdiel,prtvol,&
 
253
&  susmat,dtset%symafm,dtset%symrel,dtset%tnons,ucvol,&
 
254
&  dtfil%unkg,wff1,dtset%wtk)
 
255
 
 
256
! Print the susceptibility matrix
 
257
  do isp1=1,nspden
 
258
   do isp2=1,nspden
 
259
    write(6,'(5x,a,2i2)') 'Susceptibility matrix for spins=',isp1,isp2
 
260
    write(6,'(9x,a,13x,a,10x,a,10x,a)') "g","g'","real","imag"
 
261
    do ipw1=1,10
 
262
     do ipw2=ipw1,10
 
263
      write(6,'(2x,3i4,2x,3i4,2x,f12.8,2x,f12.8)') &
 
264
&      kg_diel(1:3,ipw1),kg_diel(1:3,ipw2),&
 
265
&      susmat(1,ipw1,isp1,ipw2,isp2),susmat(2,ipw1,isp1,ipw2,isp2)
 
266
     end do
 
267
    end do
 
268
   end do
 
269
  end do
 
270
 
 
271
! Perform deallocations
 
272
  deallocate(dielinv)
 
273
  deallocate(susmat)
 
274
  deallocate(nband_dum)
 
275
 
 
276
 else if(nfreqsus > 0) then
 
277
 
 
278
! Perform allocations
 
279
  allocate(freq(nfreqsus))
 
280
  allocate(rhor(nfft,nspden))
 
281
  allocate(wght_freq(nfreqsus))
 
282
 
 
283
! Perform initializations
 
284
  freq(:)=0.0_dp
 
285
  rhor(:,:)=0._dp
 
286
  wght_freq(:)=0.0_dp
 
287
 
 
288
! Read in the density, needed for ALDA kernel
 
289
  call status(0,dtfil%filstat,iexit,level,'call ioarr    ')
 
290
! Read rho(r) from a disk file
 
291
! Unit numbers and file name for the _KGS file
 
292
  rdwr=1;rdwrpaw=0
 
293
! Note : etotal is read here, and might serve in the tddft routine.
 
294
  fformr=52
 
295
  call ioarr(accessfil,rhor,etotal,fformr,dtfil%fildensin,hdr,&
 
296
&  nfft,nspden,rdwr,rdwrpaw,ngfft)
 
297
  call status(0,dtfil%filstat,iexit,level,'call fourdp   ')
 
298
 
 
299
!DEBUG
 
300
!leave in for MF to check the density
 
301
!  dummy=0._dp
 
302
!  do ii=1,nfft
 
303
!   dummy=dummy+rhor(ii,1)
 
304
!  end do
 
305
!  write(6,*) '%suscep: nfft=',nfft
 
306
!  write(6,*) '%suscep: dummy=',dummy*ucvol/dble(nfft)
 
307
!  write(6,*) '%suscep: ucvol=',ucvol
 
308
!  call flush(6)
 
309
!  Compute up+down rho(G) by fft
 
310
!  allocate(work(nfft))
 
311
!  work(:)=rhor(:,1)
 
312
!  call fourdp(1,rhog,work,-1,mpi_enreg,nfft,ngfft,0)
 
313
!  deallocate(work)
 
314
!ENDDEBUG
 
315
 
 
316
! Create frequency grid and weights, 2 stands for preassigned grid
 
317
  call getfreqsus(freq,wght_freq,nfreqsus,dtset%optfreqsus,dtset%freqsuslo,dtset%freqsusin)
 
318
 
 
319
!DEBUG
 
320
! write(6,*)' suscep : after getfreqsus '
 
321
! call flush(6)
 
322
!ENDDEBUG
 
323
 
 
324
  call xcacfd(cg,densymop_diel,dielar,dielop,doccde,&
 
325
&  dtfil,dtset,eigen,filsustr,freq,gbound_diel,gmet,&
 
326
&  gprimd,irrzondiel,kg,kg_diel,mband,mgfftdiel,mkmem,&
 
327
&  mpi_enreg,mpw,nfft,nfftdiel,nfreqsus,dtset%ngfft,&
 
328
&  ngfftdiel,nkpt,npwarr,npwdiel,nspden,nspinor,nsppol,&
 
329
&  nsym,occ,phnonsdiel,rhor,rmet,rprimd,ucvol,wff1,wght_freq,ncdims)
 
330
 
 
331
! Perform deallocations
 
332
  deallocate(freq)
 
333
  deallocate(rhor)
 
334
  deallocate(wght_freq)
 
335
 
 
336
 else
 
337
 
 
338
! Leave intact for testing purposes
 
339
  nfreqsus=abs(nfreqsus)
 
340
 
 
341
! Perform allocations
 
342
  allocate(freq(nfreqsus))
 
343
  allocate(susd_non_dyn(2,npwdiel,nspden,nfreqsus))
 
344
  allocate(susmat_dyn(2,npwdiel,nspden,npwdiel,nspden,nfreqsus))
 
345
 
 
346
! Perform initializations
 
347
  freq(:)=0.0_dp
 
348
  susmat_dyn(:,:,:,:,:,:)=0.0_dp
 
349
 
 
350
! Create a linear frequency grid
 
351
  freq(1)=dtset%freqsuslo
 
352
  do ifreq=2,nfreqsus
 
353
   freq(ifreq)=freq(ifreq-1)+dtset%freqsusin
 
354
  end do
 
355
 
 
356
!DEBUG
 
357
! write(6,*) '%suscep: nband_mx=', nband_mx
 
358
!ENDDEBUG
 
359
 
 
360
! Compute the dynamical susceptibility matrices
 
361
  call suscep_dyn(cg,densymop_diel,dielar,dielop,doccde,dtset,&
 
362
&  eigen,freq,gbound_diel,&
 
363
&  irrzondiel,dtset%istwfk,kg,kg_diel,&
 
364
&  mband,mgfftdiel,mkmem,mpi_enreg,mpw,dtset%nband,nband_mx,nfftdiel,nfreqsus,&
 
365
&  ngfftdiel,nkpt,npwarr,npwdiel,nspden,nspinor,nsppol,nsym,&
 
366
&  occ,dtset%occopt,phnonsdiel,prtvol,&
 
367
&  susopt,susd_non_dyn,susmat_dyn,dtset%symafm,&
 
368
&  dtset%symrel,dtset%tnons,ucvol,dtfil%unkg,wff1,dtset%wtk)
 
369
 
 
370
! Print the dynamical susceptibility matrices
 
371
  do ifreq=1,nfreqsus
 
372
   write(6,'(/,2x,a,f12.8,a)') '---Susceptibility matrices for frequency=',freq(ifreq),'i'
 
373
   do isp1=1,nspden
 
374
    do isp2=1,nspden
 
375
     write(6,'(5x,a,2i2)') 'Susceptibility matrix for spins=',isp1,isp2
 
376
     write(6,'(9x,a,13x,a,10x,a,10x,a)') "g","g'","real","imag"
 
377
     do ipw1=1,10
 
378
      do ipw2=ipw1,10
 
379
       write(6,'(2x,3i4,2x,3i4,2x,f12.8,2x,f12.8)') &
 
380
&       kg_diel(1:3,ipw1),kg_diel(1:3,ipw2),&
 
381
&       susmat_dyn(1,ipw1,isp1,ipw2,isp2,ifreq),susmat_dyn(2,ipw1,isp1,ipw2,isp2,ifreq)
 
382
      end do
 
383
     end do
 
384
    end do
 
385
   end do
 
386
  end do
 
387
 
 
388
! Perform deallocations
 
389
  deallocate(freq)
 
390
  deallocate(susd_non_dyn)
 
391
  deallocate(susmat_dyn)
 
392
 
 
393
 end if !condition nfreqsus
 
394
 
 
395
!Performs deallocations
 
396
 deallocate(cg,doccde,eigen,gbound_diel)
 
397
 deallocate(indsym,irrzondiel)
 
398
 deallocate(kg_diel,kg,npwarr,npwtot,phnonsdiel,symrec)
 
399
 
 
400
 if(mkmem==0)then
 
401
! Sequential case
 
402
  if(mpi_enreg%paral_compil_kpt==0)then
 
403
!  Unit dtfil%unkg was opened in kpgio
 
404
   close (unit=dtfil%unkg,status='delete')
 
405
 
 
406
! Parallel case
 
407
  else if(mpi_enreg%paral_compil_kpt==1)then
 
408
 
 
409
!  All procs close the file dtfil%unkg
 
410
   close(unit=dtfil%unkg)
 
411
   if(mpi_enreg%me==0)then
 
412
!   only proc 0 delete the file
 
413
    open(unit=dtfil%unkg,file=filkgs,form='unformatted',status='unknown')
 
414
    close(unit=dtfil%unkg,status='delete')
 
415
   end if
 
416
 
 
417
  end if
 
418
 end if
 
419
 
 
420
 call WffClose(wff1,ierr)
 
421
 
 
422
!Clean the header
 
423
 call hdr_clean(hdr)
 
424
 
 
425
 if(mpi_enreg%paral_compil_kpt==1)then
 
426
  deallocate(mpi_enreg%proc_distrb)
 
427
 end if
 
428
 
 
429
 write(message, '(a,a)' ) ch10,' suscep : exiting '
 
430
 call wrtout(06,message,'COLL')
 
431
 
 
432
 call status(0,dtfil%filstat,iexit,level,'exit          ')
 
433
 call timab(84,2,tsec)
 
434
 
 
435
end subroutine suscep
 
436
!!***