~siesta-pseudos-bases/siesta/trunk-psml

« back to all changes in this revision

Viewing changes to Util/Denchar/Src/stsofr.f

  • Committer: Alberto Garcia
  • Date: 2019-09-02 14:09:43 UTC
  • mfrom: (427.6.323 trunk)
  • Revision ID: albertog@icmab.es-20190902140943-mzmbe1jacgefpgxw
Sync to trunk-776 (notably nc/soc wavefunction support)


Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
! ---
2
 
! Copyright (C) 1996-2016       The SIESTA group
3
 
!  This file is distributed under the terms of the
4
 
!  GNU General Public License: see COPYING in the top directory
5
 
!  or http://www.gnu.org/copyleft/gpl.txt .
6
 
! See Docs/Contributors.txt for a list of contributors.
7
 
! ---
8
 
 
9
 
      SUBROUTINE STSOFR( NA, NO, NUO, MAXNA, NSPIN, 
10
 
     .                  ISA, IPHORB, INDXUO, LASTO, XA, CELL,
11
 
     .                  RPSI, IPSI, E, INDW, NWF, NUMWF, NK, K,
12
 
     .                  ARMUNI, IUNITCD, RMAXO,
13
 
     .                  EMIN, NE, DELTAE, ETA, XSTS, BFUNC )
14
 
C **********************************************************************
15
 
C Computes the local density of states as a function of energy
16
 
C at a given point in real space, for the simulation of STS spectra
17
 
C Coded by P. Ordejon. July 2004
18
 
C **********************************************************************
19
 
 
20
 
      use precision
21
 
      USE FDF
22
 
      USE ATMFUNCS
23
 
      USE CHEMICAL
24
 
      USE LISTSC_MODULE, ONLY: LISTSC
25
 
 
26
 
      IMPLICIT NONE
27
 
 
28
 
      INTEGER, INTENT(IN) ::
29
 
     .  NA, NO, NUO, IUNITCD, NK,
30
 
     .  NSPIN, MAXNA, NWF(NK), NUMWF, 
31
 
     .  ISA(NA), IPHORB(NO), INDXUO(NO), LASTO(0:NA),
32
 
     .  INDW(NK,NUMWF), NE, BFUNC
33
 
      real(dp), INTENT(IN) ::
34
 
     .  XA(3,NA), ARMUNI, RMAXO,
35
 
     .  EMIN, DELTAE, ETA, XSTS(3)
36
 
 
37
 
      real(dp), INTENT(IN) ::
38
 
     . CELL(3,3), 
39
 
     . RPSI(NUO,NK,NUMWF,NSPIN), IPSI(NUO,NK,NUMWF,NSPIN),
40
 
     . E(NK,NUMWF,NSPIN), K(NK,3)
41
 
 
42
 
C ****** INPUT *********************************************************
43
 
C INTEGER NA               : Total number of atoms in Supercell
44
 
C INTEGER NO               : Total number of orbitals in Supercell
45
 
C INTEGER NUO              : Total number of orbitals in Unit Cell
46
 
C INTEGER MAXNA            : Maximum number of neighbours of any atom
47
 
C INTEGER NSPIN            : Number of different spin polarizations
48
 
C                            Nspin = 1 => unpolarized, Nspin = 2 => polarized
49
 
C INTEGER ISA(NA)          : Species index of each atom
50
 
C INTEGER IPHORB(NO)       : Orital index of each orbital in its atom
51
 
C INTEGER INDXUO(NO)       : Equivalent orbital in unit cell
52
 
C INTEGER LASTO(0:NA)      : Last orbital of each atom in array iphorb
53
 
C REAL*8  XA(3,NA)         : Atomic positions in cartesian coordinates
54
 
C                            (in bohr)
55
 
C REAL*8  CELL(3,3)        : Supercell vectors CELL(IXYZ,IVECT)
56
 
C                            (in bohr)
57
 
C REAL*8 RPSI(NUO,NK,NUMWF,NSPIN): Wave function coefficients (real part)
58
 
C REAL*8 IPSI(NUO,NK,NUMWF,NSPIN): Wave function coefficients (imag part)
59
 
C REAL*8 E(NK,NUMWF,NSPIN) : Eigen energies
60
 
C INTEGER INDW(NUMWF,NK)   : Index of the wavefunctions
61
 
C INTEGER NWF(NK)          : Number of wavefncts to print for each k-point
62
 
C INTEGER NUMWF            : Max num of wavefncts to print a given k-point
63
 
C INTEGER NK               : Number of k-points
64
 
C REAL*8 K(NK,3)           : k-points
65
 
C REAL*8  ARMUNI           : Conversion factor for the charge density
66
 
C INTEGER IUNITCD          : Unit of the charge density
67
 
C REAL*8  RMAXO            : Maximum range of basis orbitals
68
 
C REAL*8 EMIN              : Minimum energy in STS curve
69
 
C INTEGER NE               : Number of points in STS curve
70
 
C REAL*8 DELTAE            : Energy step between points in STS curve
71
 
C REAL*8 ETA               : Lorenzian or gaussian width
72
 
C REAL*8 XSTS(3)           : Position where STS is calculated
73
 
C INTEGER BFUNC            : Broadening function
74
 
C                            1 = Lorentzian   2 = Gaussian
75
 
C **********************************************************************
76
 
 
77
 
      INTEGER, DIMENSION(:), ALLOCATABLE :: JNA
78
 
 
79
 
      REAL, DIMENSION(:,:), allocatable :: RWF, IMWF, MWF, PWF
80
 
 
81
 
      real(dp), DIMENSION(:), ALLOCATABLE :: R2IJ, LDOS
82
 
 
83
 
      real(dp), DIMENSION(:,:), ALLOCATABLE ::  XIJ
84
 
 
85
 
      INTEGER
86
 
     .  IA, ISEL, NNA, UNIT, IE
87
 
 
88
 
      INTEGER
89
 
     .  I, J, IN, IAT1, IAT2, JO, IO, IUO, IAVEC, IAVEC1, IAVEC2, 
90
 
     .  IS1, IS2, IPHI1, IPHI2, IND, IX, IY, IZ, NX, NY, NZ, IWF, 
91
 
     .  INDWF, IZA(NA), IK
92
 
 
93
 
      real(dp)
94
 
     .  RMAX, XPO(3), RMAX2, XVEC1(3),
95
 
     .  XVEC2(3), PHIMU, GRPHIMU(3),
96
 
     .  OCELL(3,3), PHASE, SI, CO, PI, ENER, PSI2
97
 
 
98
 
      real(dp)
99
 
     .  RWAVE, RWAVEUP, RWAVEDN,
100
 
     .  IWAVE, IWAVEUP, IWAVEDN
101
 
 
102
 
      LOGICAL FIRST
103
 
 
104
 
      CHARACTER
105
 
     .  SNAME*40, FNAME*60, 
106
 
     .  CHAR1*10, CHAR2*10, 
107
 
     .  EXT*20, EXT2*25
108
 
 
109
 
      EXTERNAL
110
 
     .  IO_ASSIGN, IO_CLOSE, NEIGHB
111
 
 
112
 
C **********************************************************************
113
 
C INTEGER IA               : Atom whose neighbours are needed.
114
 
C                            A routine initialization must be done by
115
 
C                            a first call with IA = 0
116
 
C                            If IA0=0, point X0 is used as origin instead
117
 
C INTEGER ISEL             : Single-counting switch (0=No, 1=Yes). If ISEL=1,
118
 
C                            only neighbours with JA.LE.IA are included in JNA
119
 
C INTEGER NNA              : Number of non-zero orbitals at a point in 
120
 
C                            real space
121
 
C INTEGER JNA(MAXNA)       : Atom index of neighbours. The neighbours
122
 
C                            atoms might be in the supercell
123
 
C REAL*8  XIJ(3,MAXNA)     : Vectors from point in real space to orbitals
124
 
C REAL*8  R2IJ(MAXNA)      : Squared distance to atomic orbitals
125
 
C REAL*8  XPO(3)           : Coordinates of the point of the plane respect
126
 
C                            we are going to calculate the neighbours orbitals
127
 
C INTEGER IZA(NA)          : Atomic number of each atom
128
 
C **********************************************************************
129
 
 
130
 
 
131
 
C Allocate some variables ---------------------------------------------
132
 
      IF (NSPIN .NE. 1 .AND. NSPIN .NE. 2) THEN
133
 
        WRITE(6,*)'BAD NUMBER NSPIN IN STS.F'
134
 
        WRITE(6,*)'NSPIN = ',NSPIN
135
 
        WRITE(6,*)'IT MUST BE 1 => NON POLARIZED, OR 2 = > POLARIZED'
136
 
        STOP
137
 
      ENDIF
138
 
 
139
 
      PI = 4.0D0 * ATAN(1.0D0)
140
 
 
141
 
      ALLOCATE(LDOS(NE))
142
 
      CALL MEMORY('A','D',SIZE(LDOS),'stsofr')
143
 
C Initiallize ldos vector ---------------------------------------------
144
 
 
145
 
      DO IE = 1,NE
146
 
        LDOS(IE) = 0.0d0
147
 
      ENDDO
148
 
 
149
 
C Initialize neighbour subroutine --------------------------------------
150
 
      IA = 0
151
 
      ISEL = 0
152
 
      RMAX = RMAXO
153
 
      NNA  = MAXNA
154
 
      IF (ALLOCATED(JNA)) THEN
155
 
        CALL MEMORY('D','I',SIZE(JNA),'stsofr')
156
 
        DEALLOCATE(JNA)
157
 
      ENDIF
158
 
      IF (ALLOCATED(R2IJ)) THEN
159
 
        CALL MEMORY('D','D',SIZE(R2IJ),'stsofr')
160
 
        DEALLOCATE(R2IJ)
161
 
      ENDIF
162
 
      IF (ALLOCATED(XIJ)) THEN
163
 
        CALL MEMORY('D','D',SIZE(XIJ),'stsofr')
164
 
        DEALLOCATE(XIJ)
165
 
      ENDIF
166
 
      ALLOCATE(JNA(MAXNA))
167
 
      CALL MEMORY('A','I',MAXNA,'stsofr')
168
 
      ALLOCATE(R2IJ(MAXNA))
169
 
      CALL MEMORY('A','D',MAXNA,'stsofr')
170
 
      ALLOCATE(XIJ(3,MAXNA))
171
 
      CALL MEMORY('A','D',3*MAXNA,'stsofr')
172
 
 
173
 
      FIRST = .TRUE.
174
 
      DO I = 1,3
175
 
        XPO(I) = 0.D0
176
 
      ENDDO
177
 
 
178
 
      CALL NEIGHB( CELL, RMAX, NA, XA, XPO, IA, ISEL, 
179
 
     .             NNA, JNA, XIJ, R2IJ, FIRST )
180
 
 
181
 
      FIRST = .FALSE.
182
 
      RMAX2 =  RMAXO**2
183
 
 
184
 
 
185
 
C Assign the point where STS will be computed
186
 
 
187
 
      DO IX = 1,3
188
 
        XPO(IX) = XSTS(IX)
189
 
      ENDDO
190
 
 
191
 
C Open file to store sts spectrum   -----------------------------------
192
 
      SNAME = FDF_STRING('SystemLabel','siesta')
193
 
      FNAME = TRIM(SNAME)//'.STS'
194
 
      CALL IO_ASSIGN(UNIT)
195
 
      OPEN(UNIT = UNIT, FILE = FNAME, STATUS = 'UNKNOWN',
196
 
     .     FORM = 'FORMATTED')
197
 
      REWIND(UNIT)
198
 
 
199
 
      WRITE(6,'(A)')
200
 
      WRITE(6,'(A)')
201
 
     .  '   Generating STS spectra at point'
202
 
      WRITE(6,'(3F10.5)')
203
 
     .  XPO(1),XPO(2),XPO(3)
204
 
      WRITE(6,'(A,I6)')
205
 
     .  '   Please, wait....'
206
 
      WRITE(6,'(A)')
207
 
 
208
 
C Localize non-zero orbitals each point in real space ---------------
209
 
     
210
 
      IA   = 0
211
 
      ISEL = 0
212
 
      NNA  = MAXNA
213
 
 
214
 
      CALL NEIGHB( CELL, RMAX, NA, XA, XPO, IA, ISEL, 
215
 
     .             NNA, JNA, XIJ, R2IJ, FIRST )
216
 
 
217
 
 
218
 
C Loop over wavefunctions 
219
 
 
220
 
      DO IK  = 1, NK
221
 
      DO IWF = 1, NWF(IK)
222
 
 
223
 
        INDWF = INDW(IK,IWF)
224
 
 
225
 
 
226
 
C Initialize the value of the wave function  -----------------------
227
 
        RWAVE  = 0.D0
228
 
        RWAVEUP   = 0.D0
229
 
        RWAVEDN   = 0.D0
230
 
        IWAVE  = 0.D0
231
 
        IWAVEUP   = 0.D0
232
 
        IWAVEDN   = 0.D0
233
 
 
234
 
C Loop over Non-zero orbitals ------------------------------------------ 
235
 
        DO 110 IAT1 = 1, NNA
236
 
          IF( R2IJ(IAT1) .GT. RMAX2 ) EXIT
237
 
 
238
 
          IAVEC1   = JNA(IAT1)
239
 
          IS1      = ISA(IAVEC1)
240
 
          XVEC1(1) = -XIJ(1,IAT1)
241
 
          XVEC1(2) = -XIJ(2,IAT1)
242
 
          XVEC1(3) = -XIJ(3,IAT1)
243
 
 
244
 
C Calculate phase of Bloch wavefunctions
245
 
 
246
 
          PHASE = K(IK,1)*(XPO(1)+XIJ(1,IAT1))+
247
 
     .            K(IK,2)*(XPO(2)+XIJ(2,IAT1))+
248
 
     .            K(IK,3)*(XPO(3)+XIJ(3,IAT1))
249
 
 
250
 
          SI=SIN(PHASE)
251
 
          CO=COS(PHASE)
252
 
 
253
 
          DO 120 IO = LASTO(IAVEC1-1) + 1, LASTO(IAVEC1)
254
 
            IPHI1 = IPHORB(IO)
255
 
            IUO   = INDXUO(IO)
256
 
            CALL PHIATM( IS1, IPHI1, XVEC1, PHIMU, GRPHIMU )
257
 
 
258
 
            IF ( NSPIN .EQ. 1 ) THEN
259
 
              RWAVE  = RWAVE  + PHIMU * 
260
 
     .        (RPSI(IUO,IK,IWF,1)*CO - IPSI(IUO,IK,IWF,1)*SI)
261
 
              IWAVE  = IWAVE  + PHIMU * 
262
 
     .        (RPSI(IUO,IK,IWF,1)*SI + IPSI(IUO,IK,IWF,1)*CO)
263
 
            ELSEIF (NSPIN .EQ. 2) THEN 
264
 
              RWAVEUP  = RWAVEUP  + PHIMU * 
265
 
     .        (RPSI(IUO,IK,IWF,1)*CO - IPSI(IUO,IK,IWF,1)*SI)
266
 
              IWAVEUP  = IWAVEUP  + PHIMU * 
267
 
     .        (RPSI(IUO,IK,IWF,1)*SI + IPSI(IUO,IK,IWF,1)*CO)
268
 
              RWAVEDN  = RWAVEDN  + PHIMU * 
269
 
     .        (RPSI(IUO,IK,IWF,2)*CO - IPSI(IUO,IK,IWF,2)*SI)
270
 
              IWAVEDN  = IWAVEDN  + PHIMU * 
271
 
     .        (RPSI(IUO,IK,IWF,2)*SI + IPSI(IUO,IK,IWF,2)*CO)
272
 
            ENDIF
273
 
 
274
 
 
275
 
 
276
 
 120      ENDDO
277
 
 110    ENDDO
278
 
 
279
 
 
280
 
C Loop over energies to calculate the local density of states 
281
 
 
282
 
            ENER = EMIN
283
 
 
284
 
            DO IE = 1,NE
285
 
 
286
 
              IF (NSPIN .EQ. 1) THEN
287
 
                PSI2 = RWAVE**2+IWAVE**2
288
 
                IF (BFUNC .EQ. 1) THEN
289
 
                  LDOS(IE) = LDOS(IE) + (ARMUNI/NK) * 2.0 * PSI2 *
290
 
     .             (ETA/PI) / ((ENER - E(IK,IWF,1))**2 + ETA**2)
291
 
                ELSE IF (BFUNC .EQ. 2) THEN
292
 
                  LDOS(IE) = LDOS(IE) + (ARMUNI/NK) * 2.0 * PSI2 *
293
 
     .             (1.0d0/(ETA*DSQRT(PI))) * 
294
 
     .             DEXP(-((ENER - E(IK,IWF,1))/ETA)**2)
295
 
                ELSE 
296
 
                  STOP 'Wrong convolution function in stsofr.f'
297
 
                ENDIF
298
 
              ELSE IF (NSPIN .EQ. 2) THEN
299
 
                PSI2 = RWAVEUP**2+IWAVEUP**2
300
 
                IF (BFUNC .EQ. 1) THEN
301
 
                  LDOS(IE) = LDOS(IE) + (ARMUNI/NK) * 2.0 * PSI2 *
302
 
     .             (ETA/PI) / ((ENER - E(IK,IWF,1))**2 + ETA**2)
303
 
                ELSE IF (BFUNC .EQ. 2) THEN
304
 
                  LDOS(IE) = LDOS(IE) + (ARMUNI/NK) * 2.0 * PSI2 *
305
 
     .             (1.0d0/(ETA*DSQRT(PI))) * 
306
 
     .             DEXP(-((ENER - E(IK,IWF,1))/ETA)**2)
307
 
                ELSE 
308
 
                  STOP 'Wrong convolution function in stsofr.f'
309
 
                ENDIF
310
 
                PSI2 = RWAVEDN**2+IWAVEDN**2
311
 
                IF (BFUNC .EQ. 1) THEN
312
 
                  LDOS(IE) = LDOS(IE) + (ARMUNI/NK) * 2.0 * PSI2 *
313
 
     .             (ETA/PI) / ((ENER - E(IK,IWF,2))**2 + ETA**2)
314
 
                ELSE IF (BFUNC .EQ. 2) THEN
315
 
                  LDOS(IE) = LDOS(IE) + (ARMUNI/NK) * 2.0 * PSI2 *
316
 
     .             (1.0d0/(ETA*DSQRT(PI))) * 
317
 
     .             DEXP(-((ENER - E(IK,IWF,2))/ETA)**2)
318
 
                ELSE 
319
 
                  STOP 'Wrong convolution function in stsofr.f'
320
 
                ENDIF
321
 
              ELSE 
322
 
                STOP 'Wrong NSPIN'
323
 
              ENDIF
324
 
 
325
 
              ENER = ENER + DELTAE
326
 
            ENDDO
327
 
           
328
 
      ENDDO
329
 
      ENDDO
330
 
 
331
 
 
332
 
C Print out LDOS -------------------------------------------------
333
 
      WRITE(UNIT,'(A)')  '# LDOS vs. Energy curve'
334
 
      WRITE(UNIT,'(A)')  '# '
335
 
      WRITE(UNIT,'(A,3e13.5,A)')
336
 
     .             '# LDOS computed on point ',(XSTS(I),I=1,3),' bohr'
337
 
      IF (IUNITCD .EQ. 1) THEN
338
 
        WRITE(UNIT,'(A)') '# in units of elecron/(bohr)**3/eV'
339
 
      ELSE IF (IUNITCD .EQ. 2) THEN
340
 
        WRITE(UNIT,'(A)') '# in units of elecron/(ang)**3/eV'
341
 
      ELSE IF (IUNITCD .EQ. 3) THEN
342
 
        WRITE(UNIT,'(A)') '# in units of elecron/unitcell/eV'
343
 
      ELSE 
344
 
        STOP 'Wrong IUNITCD in stsofr.f'
345
 
      ENDIF
346
 
      WRITE(UNIT,'(A)') '# '
347
 
      WRITE(UNIT,'(A)') '# Energy in eV)'
348
 
      WRITE(UNIT,'(A)') '# '
349
 
      WRITE(UNIT,'(A)') '#       Energy           LDOS'
350
 
      WRITE(UNIT,'(A)') '# '
351
 
 
352
 
      ENER = EMIN
353
 
      DO IE = 1,NE
354
 
        WRITE(UNIT,'(2f15.5)') ENER,LDOS(IE)
355
 
        ENER = ENER + DELTAE
356
 
      ENDDO
357
 
 
358
 
      WRITE(6,'(A)')
359
 
      WRITE(6,'(A)')
360
 
     .  '   Your STS output file is:'
361
 
      WRITE(6,'(A,A)') '   ',FNAME
362
 
 
363
 
      CALL IO_CLOSE(UNIT)
364
 
 
365
 
 
366
 
      CALL MEMORY('D','D',SIZE(LDOS),'stsofr')
367
 
      DEALLOCATE(LDOS)
368
 
 
369
 
 
370
 
      RETURN    
371
 
      END