File: derived_object.f90

package info (click to toggle)
espresso 6.7-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 311,068 kB
  • sloc: f90: 447,429; ansic: 52,566; sh: 40,631; xml: 37,561; tcl: 20,077; lisp: 5,923; makefile: 4,503; python: 4,379; perl: 1,219; cpp: 761; fortran: 618; java: 568; awk: 128
file content (330 lines) | stat: -rw-r--r-- 11,282 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
!this module contains objected derived and contracted 
MODULE derived_objects

  USE kinds, ONLY : DP

  TYPE prod_proj
!terms <\mathcal{E}_\alpha|u_{k,c}u_{k,v}^*>
!k ponits distributed on MPI tasks as bands object
     INTEGER :: numv !number of valence states (those considered for excitons only) 
     INTEGER :: numc !number of conduction states 
     INTEGER :: nk!total number of k, points 
     INTEGER :: nk_loc!local number of k points 
     INTEGER :: ik_first!first local k point 
     INTEGER :: ik_last!last local k point 
     INTEGER :: ntot_e!dimension of global to all k, basis for KS states
     INTEGER :: nprod_e!number of product terms 
     COMPLEX(kind=DP), DIMENSION(:,:,:,:), POINTER :: javc! (nprod_e,numv,numc,nk_loc)
  END TYPE prod_proj

  TYPE prod_mix
!terms <\mathcal{E}_\alpha|(u_{k,v}u_{k',v'}^*)>
!and terms <\mathcal{E}_\alpha|(u_{k,c}u_{k',c'}^*)>
!k' distributed over MPI tasks
!k NOT distributed
     INTEGER :: numv !number of valence states (those considered for excitons only) 
     INTEGER :: numc !number of conduction states
     INTEGER :: nk!total number of k, points
     INTEGER :: nk_loc!local number of k points
     INTEGER :: ik_first!first local k point
     INTEGER :: ik_last!last local k point
     INTEGER :: ntot_e!dimension of global to all k, basis for KS states
     INTEGER :: nprod_e!number of product terms
     COMPLEX(kind=DP), DIMENSION(:,:,:,:,:), POINTER :: gvv! (nprod_e,numv,nk,numv',nk_loc)! ' means relative to nk_loc
     COMPLEX(kind=DP), DIMENSION(:,:,:,:,:), POINTER :: gcc! (nprod_e,numc,nk,numc',nk_loc)


  END TYPE prod_mix


  CONTAINS

    SUBROUTINE initialize_prod_proj(pp)
      implicit none
      TYPE(prod_proj) :: pp
      
      nullify(pp%javc)

      return
    END SUBROUTINE initialize_prod_proj



    SUBROUTINE deallocate_prod_proj(pp)
      implicit none
      TYPE(prod_proj) :: pp
      if(associated(pp%javc)) deallocate(pp%javc)
      nullify(pp%javc)
      return
    END SUBROUTINE deallocate_prod_proj






    SUBROUTINE initialize_prod_mix(pm)
      implicit none
      TYPE(prod_mix) :: pm

      nullify(pm%gvv)
      nullify(pm%gcc)

      return
    END SUBROUTINE initialize_prod_mix



    SUBROUTINE deallocate_prod_mix(pm)
      implicit none
      TYPE(prod_mix) :: pm
      if(associated(pm%gvv)) deallocate(pm%gvv)
      nullify(pm%gvv)
      if(associated(pm%gcc)) deallocate(pm%gcc)
      nullify(pm%gcc)
      return
    END SUBROUTINE deallocate_prod_mix
    

    SUBROUTINE build_prod_proj(bd,pd,pp)
!this subroutine constructs the prod_proj object
      USE simple_objects, ONLY : bands,product

      

      implicit none
      TYPE(bands), INTENT(in) :: bd
      TYPE(product), INTENT(in) :: pd
      TYPE(prod_proj), INTENT(out) :: pp

      
      INTEGER :: ik,iv,ic
      COMPLEX(kind=DP), ALLOCATABLE :: tmp_mat(:,:,:),tmp_mat2(:,:),tmp_mat3(:,:)
      COMPLEX(kind=DP), ALLOCATABLE :: zmat(:,:,:,:),zmat0(:,:),zmat1(:,:,:,:)
      LOGICAL, parameter :: debug = .false.


      pp%numv=bd%numv
      pp%numc=bd%numc
      pp%ntot_e=bd%ntot_e
      pp%nk=bd%nk
      pp%nk_loc=bd%nk_loc
      pp%ik_first=bd%ik_first
      pp%ik_last=bd%ik_last
      pp%nprod_e=pd%nprod_e
      
      if(pp%nk_loc>0) then
         allocate(pp%javc(pp%nprod_e,pp%numv, pp%numc,pp%nk_loc))
         allocate(tmp_mat(pp%nprod_e,pp%ntot_e,pp%numc))
         allocate(tmp_mat2(pp%ntot_e,pp%numv))
         allocate(tmp_mat3(pp%ntot_e,pp%numc))
         do ik=1,pp%nk_loc
            tmp_mat2(1:pp%ntot_e,1:pp%numv)=conjg(bd%omat(1:pp%ntot_e,1:pp%numv,ik))
            tmp_mat3(1:pp%ntot_e,1:pp%numc)=bd%omat(1:pp%ntot_e,pp%numv+1:pp%numv+pp%numc,ik)
            call ZGEMM('N','N',pp%nprod_e*pp%ntot_e,pp%numc,pp%ntot_e,(1.d0,0.d0),pd%fij,&
                 &pp%nprod_e*pp%ntot_e,tmp_mat3,pp%ntot_e,(0.d0,0.d0),tmp_mat,pp%nprod_e*pp%ntot_e)
            do ic=1,pp%numc
               call ZGEMM('N','N',pp%nprod_e,pp%numv,pp%ntot_e,(1.d0,0.d0),tmp_mat(1,1,ic),pp%nprod_e,tmp_mat2,pp%ntot_e,&
                   &(0.d0,0.d0),pp%javc(1,1,ic,ik),pp%nprod_e)
            enddo
         enddo
         deallocate(tmp_mat,tmp_mat2,tmp_mat3)
      else
         nullify(pp%javc)
      endif
      if(debug) then
         !test for consistency
         allocate(zmat(pp%numc,pp%numv,pp%numv,pp%numc))
         allocate(zmat0(bd%num,bd%num))
         allocate(zmat1(pd%ntot_e,pd%ntot_e,pd%ntot_e,pd%ntot_e))
         do ik=1,bd%nk_loc
            call ZGEMM('C','N',bd%num,bd%num,bd%ntot_e,(1.d0,0.d0),bd%omat(1,1,ik),bd%ntot_e,bd%omat(1,1,ik),bd%ntot_e,&
                 &(0.d0,0.d0),zmat0,bd%num)
            
            do iv=1,bd%num
               do ic=1,bd%num
                  write(*,*) 'CHECK OMAT ik, ic,iv', ik, ic, iv, zmat0(ic,iv)
               enddo
            enddo
         enddo
         call ZGEMM('C','N',pd%ntot_e*pd%ntot_e,pd%ntot_e*pd%ntot_e,pd%nprod_e,(1.d0,0.d0),pd%fij,&
              pd%nprod_e,pd%fij,pd%nprod_e,(0.d0,0.d0),zmat1,pd%ntot_e*pd%ntot_e)
         do iv=1,pd%ntot_e
            do ic=1,pd%ntot_e
               write(*,*) 'CHECK  FIJ ic,iv', ic, iv, zmat1(iv,ic,iv,ic)
            enddo
         enddo
        
         do ik=1,pp%nk_loc
            call ZGEMM('C','N',pp%numc*pp%numv,pp%numc*pp%numv,pp%nprod_e,(1.d0,0.d0),pp%javc(1,1,1,ik),pp%nprod_e,&
                 & pp%javc(1,1,1,ik),pp%nprod_e,(0.d0,0.0),zmat, pp%numc*pp%numv)
            do iv=1,pp%numv
               do ic=1,pp%numc
                  write(*,*) 'CHECK JAVC ik, ic,iv', ik, ic, iv, zmat(iv,ic,iv,ic)
               enddo
            enddo
         enddo
          deallocate(zmat,zmat0,zmat1)
       endif
      return
    END SUBROUTINE build_prod_proj

  SUBROUTINE build_prod_mix(sin,bd,pd,pm,pt)
!this subroutine constructs the prod_mix object
!COMPLEX(kind=DP), DIMENSION(:,:,:,:,:), POINTER :: gvv! (nprod_e,numv,nk,numv,nk_loc)                                     
!COMPLEX(kind=DP), DIMENSION(:,:,:,:,:), POINTER :: gcc! (nprod_e,numc,nk,numc,nk_loc)
 
     USE input_simple_exc
     USE simple_objects, ONLY : bands,product,potential
     USE mp_world, ONLY : mpime, world_comm
     USE mp, ONLY : mp_sum, mp_bcast
     USE io_global, ONLY : stdout

      implicit none

      TYPE(input_options) :: sin
      TYPE(bands), INTENT(in) :: bd
      TYPE(product), INTENT(in) :: pd
      TYPE(prod_mix), INTENT(out) :: pm
      TYPE(potential) :: pt

      INTEGER :: ik,iv,ic
      COMPLEX(kind=DP), ALLOCATABLE :: tmp_mat(:,:,:),tmp_mat2(:,:),tmp_mat3(:,:,:)
      LOGICAL, parameter :: debug = .true.
      COMPLEX(kind=DP), ALLOCATABLE :: emat(:,:)
      INTEGER :: is_mine
      INTEGER :: jk
      COMPLEX(kind=DP), ALLOCATABLE :: tmp_pot(:,:),tmp_fij(:,:,:)
      INTEGER :: ii,jj,kk

      pm%numv=bd%numv
      pm%numc=bd%numc
      pm%ntot_e=bd%ntot_e
      pm%nk=bd%nk
      pm%nk_loc=bd%nk_loc
      pm%ik_first=bd%ik_first
      pm%ik_last=bd%ik_last
      pm%nprod_e=pd%nprod_e
      if(pm%nk_loc>0) then
         allocate( pm%gvv(pm%nprod_e,pm%numv,pm%nk,pm%numv,pm%nk_loc))
         allocate( pm%gcc(pm%nprod_e,pm%numc,pm%nk,pm%numc,pm%nk_loc))
      else
         nullify(pm%gcc)
         nullify(pm%gvv)
      endif
!now do gvv
!loop on nk
!if ik is my distribute to others
!loop on nk_loc
!calculate terms
      allocate(emat(pm%ntot_e,pm%numv))
      allocate(tmp_mat2(pm%ntot_e,pm%numv))
      allocate(tmp_mat(pm%nprod_e,pm%ntot_e,pm%numv))
      allocate(tmp_mat3(pm%nprod_e,pm%numv,pm%numv))
      allocate(tmp_pot(pm%nprod_e,pm%nprod_e))
      allocate(tmp_fij(pm%nprod_e,pm%ntot_e,pm%ntot_e))

      



      do ik=1,pm%nk
         if(ik>=pm%ik_first.and.ik<=pm%ik_last) then
            emat(1:pm%ntot_e,1:pm%numv)=bd%omat(1:pm%ntot_e,1:pm%numv,ik-pm%ik_first+1)
            is_mine=mpime+1
         else
            is_mine=0
         endif
         call mp_sum(is_mine,world_comm)
         is_mine=is_mine-1
         call mp_bcast( emat,is_mine, world_comm )

         do jk=1,pm%nk_loc!on k' local

!find out q=k_i-k_j
            ii=pt%ijk(1,ik,jk+pm%ik_first-1)
            jj=pt%ijk(2,ik,jk+pm%ik_first-1)
            kk=pt%ijk(3,ik,jk+pm%ik_first-1)
            tmp_pot(1:pm%nprod_e,1:pm%nprod_e)= pt%vpotq(1:pm%nprod_e,1:pm%nprod_e,ii,jj,kk)
         
           
            
            !tmp_pot(1:pm%nprod_e,1:pm%nprod_e)=1.d0!DEBUG
            if(sin%h_level >= 3) then
               tmp_pot(1:pm%nprod_e,1:pm%nprod_e)= tmp_pot(1:pm%nprod_e,1:pm%nprod_e) +&
              &pt%wpotq(1:pm%nprod_e,1:pm%nprod_e,ii,jj,kk)
            endif
            call ZGEMM('N','N',pm%nprod_e,pm%ntot_e*pm%ntot_e,pm%nprod_e,(-1.d0,0.d0),&
                 &tmp_pot,pm%nprod_e,pd%fij,pm%nprod_e,(0.d0,0.d0),tmp_fij,pm%nprod_e)

    
            tmp_mat2(1:pm%ntot_e,1:pm%numv)=conjg(bd%omat(1:pm%ntot_e,1:pm%numv,jk))
            !call ZGEMM('N','N',pm%nprod_e*pm%ntot_e,pm%numv,pm%ntot_e,(1.d0,0.d0),pd%fij,&
            !      &pm%nprod_e*pm%ntot_e,emat,pm%ntot_e,(0.d0,0.d0),tmp_mat,pm%nprod_e*pm%ntot_e)

            call ZGEMM('N','N',pm%nprod_e*pm%ntot_e,pm%numv,pm%ntot_e,(1.d0,0.d0),tmp_fij,&
                  &pm%nprod_e*pm%ntot_e,emat,pm%ntot_e,(0.d0,0.d0),tmp_mat,pm%nprod_e*pm%ntot_e)


            do iv=1,pm%numv
                call ZGEMM('N','N',pm%nprod_e,pm%numv,pm%ntot_e,(1.d0,0.d0),tmp_mat(1,1,iv),pm%nprod_e,tmp_mat2,pm%ntot_e,&
                   &(0.d0,0.d0),tmp_mat3(1,1,iv),pm%nprod_e)
               
            enddo
            do iv=1,pm%numv
               pm%gvv(1:pm%nprod_e,1:pm%numv,ik,iv,jk)=tmp_mat3(1:pm%nprod_e,iv,1:pm%numv)
            enddo
         enddo
      enddo

      deallocate(emat)
      deallocate(tmp_mat2)
      deallocate(tmp_mat)
      deallocate(tmp_mat3)
      deallocate(tmp_pot)
      deallocate(tmp_fij)

      allocate(emat(pm%ntot_e,pm%numc))
      allocate(tmp_mat2(pm%ntot_e,pm%numc))
      allocate(tmp_mat(pm%nprod_e,pm%ntot_e,pm%numc))
      allocate(tmp_mat3(pm%nprod_e,pm%numc,pm%numc))

      do ik=1,pm%nk
         if(ik>=pm%ik_first.and.ik<=pm%ik_last) then
            emat(1:pm%ntot_e,1:pm%numc)=bd%omat(1:pm%ntot_e,pm%numv+1:pm%numv+pm%numc,ik-pm%ik_first+1)
            is_mine=mpime+1
         else
            is_mine=0
         endif
         call mp_sum(is_mine,world_comm)
         is_mine=is_mine-1
         call mp_bcast( emat,is_mine, world_comm )

         do jk=1,pm%nk_loc!on k' local                                                                                         
            tmp_mat2(1:pm%ntot_e,1:pm%numc)=conjg(bd%omat(1:pm%ntot_e,pm%numv+1:pm%numv+pm%numc,jk))
            call ZGEMM('N','N',pm%nprod_e*pm%ntot_e,pm%numc,pm%ntot_e,(1.d0,0.d0),pd%fij,&
                  &pm%nprod_e*pm%ntot_e,emat,pm%ntot_e,(0.d0,0.d0),tmp_mat,pm%nprod_e*pm%ntot_e)
            do ic=1,pm%numc
                call ZGEMM('N','N',pm%nprod_e,pm%numc,pm%ntot_e,(1.d0,0.d0),tmp_mat(1,1,ic),pm%nprod_e,tmp_mat2,pm%ntot_e,&
                   &(0.d0,0.d0),tmp_mat3(1,1,ic),pm%nprod_e)

            enddo
            do ic=1,pm%numc
               pm%gcc(1:pm%nprod_e,1:pm%numc,ik,ic,jk)=tmp_mat3(1:pm%nprod_e,ic,1:pm%numc)
            enddo
         enddo
      enddo

      deallocate(emat)
      deallocate(tmp_mat2)
      deallocate(tmp_mat)
      deallocate(tmp_mat3)




    END SUBROUTINE build_prod_mix



END MODULE derived_objects