pdep_db.f90 13.5 KB
Newer Older
Marco Govoni's avatar
Marco Govoni committed
1
!
2
! Copyright (C) 2015-2017 M. Govoni 
Marco Govoni's avatar
Marco Govoni committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
! This file is distributed under the terms of the
! GNU General Public License. See the file `License'
! in the root directory of the present distribution,
! or http://www.gnu.org/copyleft/gpl.txt .
!
! This file is part of WEST.
!
! Contributors to this file: 
! Marco Govoni
!
!-----------------------------------------------------------------------
MODULE pdep_db
  !----------------------------------------------------------------------------
  !
Marco Govoni's avatar
Marco Govoni committed
17
  USE kinds,     ONLY : DP
Marco Govoni's avatar
Marco Govoni committed
18
19
20
21
22
  !
  IMPLICIT NONE
  !
  !
  CONTAINS
23
24
    !
    SUBROUTINE generate_pdep_fname( fname, j, iq)
Victor Yu's avatar
Victor Yu committed
25
26
       !
       IMPLICIT NONE
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
       !
       ! I/O 
       ! 
       CHARACTER(LEN=25), INTENT(OUT) :: fname
       INTEGER, INTENT(IN) :: j 
       INTEGER, INTENT(IN), OPTIONAL :: iq
       !
       ! Workspace 
       !
       INTEGER,PARAMETER :: default_iq = 1
       INTEGER :: iq_
       CHARACTER(LEN=9) :: label_j, label_q
       !
       IF( PRESENT(iq) ) THEN 
          iq_ = iq
       ELSE
          iq_ = default_iq
       ENDIF 
       !
       WRITE(label_j,'(i9.9)') j
       WRITE(label_q,'(i9.9)') iq_
       fname = "Q"//TRIM(ADJUSTL(label_q))//"E"//TRIM(ADJUSTL(label_j))//".json" 
       !
    END SUBROUTINE 
Marco Govoni's avatar
Marco Govoni committed
51
52
53
54
55
56
57
    !
    !
    ! *****************************
    ! PDEP WRITE
    ! *****************************
    !
    !------------------------------------------------------------------------
58
    SUBROUTINE pdep_db_write( iq, lprintinfo )
Marco Govoni's avatar
Marco Govoni committed
59
60
61
62
63
64
      !------------------------------------------------------------------------
      !
      USE mp,                   ONLY : mp_bcast,mp_barrier
      USE mp_world,             ONLY : mpime,root,world_comm
      USE mp_global,            ONLY : my_image_id
      USE io_global,            ONLY : stdout 
Marco Govoni's avatar
Marco Govoni committed
65
      USE westcom,              ONLY : wstat_calculation,n_pdep_times,n_pdep_eigen,n_pdep_maxiter,n_dfpt_maxiter, &
Marco Govoni's avatar
Marco Govoni committed
66
                                     & n_steps_write_restart,n_pdep_restart_from_itr,n_pdep_read_from_file,trev_pdep, &
Marco Govoni's avatar
Marco Govoni committed
67
                                     & tr2_dfpt,l_deflate,l_kinetic_only,ev,dvg,west_prefix,trev_pdep_rel, &
Govoni's avatar
Govoni committed
68
                                     & l_minimize_exx_if_active,l_use_ecutrho,wstat_save_dir,logfile 
Marco Govoni's avatar
Marco Govoni committed
69
70
      USE pdep_io,              ONLY : pdep_merge_and_write_G 
      USE io_push,              ONLY : io_push_bar
71
72
73
74
75
76
      USE distribution_center,  ONLY : pert
      USE types_bz_grid,        ONLY : q_grid 
      USE json_module,          ONLY : json_file, json_value, json_core
      USE cell_base,            ONLY : celldm,at,bg,tpiba
      USE gvect,                ONLY : ecutrho
      USE gvecw,                ONLY : ecutwfc
Marco Govoni's avatar
Marco Govoni committed
77
      !
78
      !
Marco Govoni's avatar
Marco Govoni committed
79
80
      IMPLICIT NONE
      !
81
      ! I/O 
82
      !
83
      INTEGER, INTENT(IN), OPTIONAL :: iq
84
      LOGICAL, INTENT(IN), OPTIONAL :: lprintinfo
85
86
87
88
89
90
91
92
93
94
95
      !
      ! Workspace
      ! 
      ! optional 
      INTEGER, PARAMETER :: default_iq = 1 
      INTEGER            :: iq_
      LOGICAL, PARAMETER :: default_lprintinfo = .TRUE.
      LOGICAL            :: lprintinfo_
      ! labels  
      CHARACTER(LEN=9) :: label_i
      ! time 
Marco Govoni's avatar
Marco Govoni committed
96
97
98
      REAL(DP), EXTERNAL    :: GET_CLOCK
      REAL(DP) :: time_spent(2)
      CHARACTER(20),EXTERNAL :: human_readable_time
99
      ! scratch  
Marco Govoni's avatar
Marco Govoni committed
100
101
      INTEGER :: iunout,global_j,local_j
      INTEGER :: ierr
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
      ! json
      TYPE(json_core) :: jcor
      TYPE(json_file) :: json
      TYPE(json_value),POINTER :: jval
      INTEGER :: iunit, n_elements, ielement, myiq, write_element 
      LOGICAL :: found 
      ! files
      CHARACTER(LEN=:),ALLOCATABLE :: summary_file
      CHARACTER(LEN=:),ALLOCATABLE  :: eigenpot_filename(:)
      CHARACTER(LEN=:),ALLOCATABLE  :: fname
      LOGICAL :: lexists
      !
      ! Assign defaut to optional parameters 
      !
      IF(PRESENT(iq)) THEN 
         iq_ = iq 
      ELSE 
         iq_ = default_iq
      ENDIF
      IF(PRESENT(lprintinfo)) THEN 
         lprintinfo_ = lprintinfo
      ELSE 
         lprintinfo_ = default_lprintinfo
      ENDIF
Govoni's avatar
Govoni committed
126
      !
127
      ! MPI barrier
Marco Govoni's avatar
Marco Govoni committed
128
129
130
      !
      CALL mp_barrier(world_comm)
      !
131
      ! Start clock
Marco Govoni's avatar
Marco Govoni committed
132
133
134
      !
      CALL start_clock('pdep_db')
      time_spent(1)=get_clock('pdep_db')
Marco Govoni's avatar
Marco Govoni committed
135
      !
136
137
138
139
140
      ! Set filenames
      !
      IF(ALLOCATED(eigenpot_filename)) DEALLOCATE(eigenpot_filename)
      ALLOCATE( CHARACTER(LEN=25) :: eigenpot_filename(n_pdep_eigen) )
      DO global_j = 1, n_pdep_eigen
141
         CALL generate_pdep_fname( eigenpot_filename(global_j), global_j, iq_) 
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
      ENDDO
      IF(ALLOCATED(summary_file)) DEALLOCATE(summary_file)
      summary_file = TRIM(ADJUSTL(wstat_save_dir)) // "/summary.json"
      !
      ! Create summary file if it does not exist
      !
      IF ( mpime == root ) THEN 
        !
        INQUIRE(FILE=summary_file, EXIST=lexists)
        IF( (.NOT. lexists) ) THEN
          CALL json%initialize()
          CALL json%add('dielectric_matrix.domain.a1',celldm(1)*at(1:3,1))
          CALL json%add('dielectric_matrix.domain.a2',celldm(1)*at(1:3,2))
          CALL json%add('dielectric_matrix.domain.a3',celldm(1)*at(1:3,3))
          CALL json%add('dielectric_matrix.domain.b1',tpiba*bg(1:3,1))
          CALL json%add('dielectric_matrix.domain.b2',tpiba*bg(1:3,2))
          CALL json%add('dielectric_matrix.domain.b3',tpiba*bg(1:3,3))
          CALL jcor%create_array(jval,"pdep")
          CALL json%add("dielectric_matrix.pdep",jval)
          !
          OPEN(NEWUNIT= iunit, FILE= summary_file )
Victor Yu's avatar
Victor Yu committed
163
          CALL json%print( iunit )
164
165
166
167
168
169
170
171
172
          CLOSE( iunit )
          !
          CALL json%destroy()
        ENDIF
        !
      ENDIF 
      !
      ! Update summary file with current structure 
      !
Marco Govoni's avatar
Marco Govoni committed
173
174
      IF ( mpime == root ) THEN
         !
Marco Govoni's avatar
Marco Govoni committed
175
         CALL json%initialize()
Victor Yu's avatar
Victor Yu committed
176
         CALL json%load( filename = summary_file )
Marco Govoni's avatar
Marco Govoni committed
177
         !
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
         CALL json%info('dielectric_matrix.pdep',n_children=n_elements)
         write_element = n_elements + 1
         DO ielement = 1, n_elements
            WRITE(label_i,'(i9)') ielement
            CALL json%get('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').iq', myiq, found) 
            IF( found ) THEN  
               IF (myiq /= iq_ ) CYCLE 
               write_element = ielement
               EXIT
            ENDIF
         ENDDO
         WRITE(label_i,'(i9)') write_element
         CALL json%add('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').iq', iq_)
         CALL json%add('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').q', q_grid%p_cryst(1:3,iq_) )
         CALL json%add('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').eigenval' , ev(1:n_pdep_eigen) )
         CALL json%add('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').eigenvec' , eigenpot_filename(1:n_pdep_eigen))
Marco Govoni's avatar
Marco Govoni committed
194
         !
195
         OPEN( NEWUNIT=iunit, FILE=summary_file )
Victor Yu's avatar
Victor Yu committed
196
         CALL json%print( iunit )
Marco Govoni's avatar
Marco Govoni committed
197
198
         CLOSE( iunit )
         CALL json%destroy()
Marco Govoni's avatar
Marco Govoni committed
199
         !
Marco Govoni's avatar
Marco Govoni committed
200
      ENDIF
Marco Govoni's avatar
Marco Govoni committed
201
      !
202
      ! Dump eigenvectors
Marco Govoni's avatar
Marco Govoni committed
203
204
205
206
207
208
209
210
      !
      DO local_j=1,pert%nloc
         !
         ! local -> global
         !
         global_j = pert%l2g(local_j)
         IF(global_j>n_pdep_eigen) CYCLE
         ! 
211
212
         fname = TRIM(ADJUSTL(wstat_save_dir)) // "/"// TRIM(ADJUSTL(eigenpot_filename(global_j))) 
         CALL pdep_merge_and_write_G(fname,dvg(:,local_j),iq_)
Marco Govoni's avatar
Marco Govoni committed
213
214
215
         !
      ENDDO
      !
216
      ! MPI barrier
Marco Govoni's avatar
Marco Govoni committed
217
218
219
      !
      CALL mp_barrier( world_comm )
      !
220
      ! timing
Marco Govoni's avatar
Marco Govoni committed
221
222
223
224
      !
      time_spent(2)=get_clock('pdep_db')
      CALL stop_clock('pdep_db')
      !
225
226
227
228
229
230
231
232
233
234
235
      IF (lprintinfo_) THEN
         WRITE(stdout,'(  5x," ")')
         CALL io_push_bar()
         WRITE(stdout, "(5x, 'SAVE written in ',a20)") human_readable_time(time_spent(2)-time_spent(1)) 
         WRITE(stdout, "(5x, 'In location : ',a)") TRIM(ADJUSTL( wstat_save_dir ))  
         CALL io_push_bar()
      ENDIF 
      !
      IF(ALLOCATED(eigenpot_filename)) DEALLOCATE(eigenpot_filename)
      IF(ALLOCATED(summary_file)) DEALLOCATE(summary_file)
      IF(ALLOCATED(fname)) DEALLOCATE(fname)
Marco Govoni's avatar
Marco Govoni committed
236
237
238
239
240
241
242
243
244
      !
    END SUBROUTINE
    !
    !
    ! *****************************
    ! PDEP READ
    ! *****************************
    !
    !------------------------------------------------------------------------
245
    SUBROUTINE pdep_db_read( nglob_to_be_read, iq, lprintinfo )
Marco Govoni's avatar
Marco Govoni committed
246
247
      !------------------------------------------------------------------------
      !
248
      USE westcom,             ONLY : n_pdep_eigen,ev,dvg,west_prefix,npwqx,wstat_save_dir
Marco Govoni's avatar
Marco Govoni committed
249
250
251
252
253
254
255
      USE io_global,           ONLY : stdout 
      USE mp,                  ONLY : mp_bcast,mp_barrier
      USE mp_world,            ONLY : world_comm,mpime,root
      USE mp_global,           ONLY : my_image_id
      USE pdep_io,             ONLY : pdep_read_G_and_distribute
      USE io_push,             ONLY : io_push_bar
      USE distribution_center, ONLY : pert
256
      USE json_module,         ONLY : json_file, json_value, json_core
Marco Govoni's avatar
Marco Govoni committed
257
258
259
      !
      IMPLICIT NONE
      !
260
      ! I/O
Marco Govoni's avatar
Marco Govoni committed
261
      !
262
263
264
265
266
267
268
269
270
271
272
273
274
275
      INTEGER, INTENT(IN) :: nglob_to_be_read
      INTEGER, INTENT(IN), OPTIONAL :: iq
      LOGICAL, INTENT(IN), OPTIONAL :: lprintinfo
      ! 
      ! Workspace
      !
      ! optional 
      INTEGER, PARAMETER :: default_iq = 1 
      INTEGER            :: iq_  
      LOGICAL, PARAMETER :: default_lprintinfo = .TRUE.  
      LOGICAL            :: lprintinfo_
      ! labels
      CHARACTER(LEN=9)      :: label_i
      ! time 
Marco Govoni's avatar
Marco Govoni committed
276
277
278
      REAL(DP), EXTERNAL    :: GET_CLOCK
      REAL(DP) :: time_spent(2)
      CHARACTER(20),EXTERNAL :: human_readable_time
279
      ! scratch 
Marco Govoni's avatar
Marco Govoni committed
280
281
282
283
      INTEGER :: ierr, n_eigen_to_get
      INTEGER :: tmp_n_pdep_eigen
      INTEGER :: dime, iun, global_j, local_j
      REAL(DP),ALLOCATABLE :: tmp_ev(:)
284
285
      ! json managers
      TYPE(json_core) :: jcor
Govoni's avatar
Govoni committed
286
      TYPE(json_file) :: json
287
288
289
290
291
292
293
      TYPE(json_value),POINTER :: jval
      INTEGER :: iunit, n_elements, ielement, myiq 
      LOGICAL :: found
      INTEGER,ALLOCATABLE :: ilen(:)
      ! files
      CHARACTER(LEN=:),ALLOCATABLE :: eigenpot_filename(:) 
      CHARACTER(LEN=:),ALLOCATABLE :: fname
Marco Govoni's avatar
Marco Govoni committed
294
      !
295
296
297
298
299
300
301
302
303
304
305
306
307
308
      ! Assign defaut to optional parameters 
      !
      IF(PRESENT(iq)) THEN 
         iq_ = iq 
      ELSE 
         iq_ = default_iq
      ENDIF
      IF(PRESENT(lprintinfo)) THEN 
         lprintinfo_ = lprintinfo
      ELSE 
         lprintinfo_ = default_lprintinfo
      ENDIF
      !
      ! MPI barrier 
Marco Govoni's avatar
Marco Govoni committed
309
310
311
312
313
314
315
316
317
      !
      CALL mp_barrier(world_comm)
      !
      CALL start_clock('pdep_db')
      !
      ! TIMING
      !
      time_spent(1)=get_clock('pdep_db')
      !
Marco Govoni's avatar
Marco Govoni committed
318
319
      ! 1)  READ THE INPUT FILE
      !
Marco Govoni's avatar
Marco Govoni committed
320
      !
Marco Govoni's avatar
Marco Govoni committed
321
      IF ( mpime == root ) THEN
Marco Govoni's avatar
Marco Govoni committed
322
         !
Marco Govoni's avatar
Marco Govoni committed
323
         CALL json%initialize()
Victor Yu's avatar
Victor Yu committed
324
         CALL json%load( filename = TRIM(ADJUSTL(wstat_save_dir)) // "/summary.json" )
325
326
327
         IF( json%failed() ) THEN 
            CALL errore("", "Cannot open: " // TRIM(ADJUSTL(wstat_save_dir)) // "/summary.json", 1 )
         ENDIF 
Marco Govoni's avatar
Marco Govoni committed
328
         ! 
329
330
331
332
333
334
335
336
337
338
339
340
341
342
         !CALL json%get('dielectric_matrix.n_pdep_eigen', tmp_n_pdep_eigen, found)
         CALL json%info('dielectric_matrix.pdep',n_children=n_elements)
         !
         DO ielement = 1, n_elements
            WRITE(label_i,'(i9)') ielement
            CALL json%get('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').iq', myiq, found) 
            IF( found ) THEN
               IF( myiq /= iq_ ) CYCLE 
               CALL json%get('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').eigenval',tmp_ev)
               CALL json%get('dielectric_matrix.pdep('//TRIM(ADJUSTL(label_i))//').eigenvec',eigenpot_filename,ilen=ilen)
               tmp_n_pdep_eigen = SIZE(tmp_ev,1)
               EXIT
            ENDIF
         ENDDO
Marco Govoni's avatar
Marco Govoni committed
343
         !
Marco Govoni's avatar
Marco Govoni committed
344
         CALL json%destroy()
Marco Govoni's avatar
Marco Govoni committed
345
346
347
348
         !
      ENDIF
      !
      CALL mp_bcast( tmp_n_pdep_eigen, root, world_comm )
Marco Govoni's avatar
Marco Govoni committed
349
      !
Marco Govoni's avatar
Marco Govoni committed
350
      ! In case nglob_to_be_read is 0, overwrite it with the read value 
Marco Govoni's avatar
Marco Govoni committed
351
352
      !
      IF (nglob_to_be_read==0) THEN 
Marco Govoni's avatar
Marco Govoni committed
353
354
         n_eigen_to_get = tmp_n_pdep_eigen
         n_pdep_eigen=tmp_n_pdep_eigen
Marco Govoni's avatar
Marco Govoni committed
355
      ELSE
Marco Govoni's avatar
Marco Govoni committed
356
         n_eigen_to_get = MIN(tmp_n_pdep_eigen,nglob_to_be_read)
Marco Govoni's avatar
Marco Govoni committed
357
      ENDIF
Marco Govoni's avatar
Marco Govoni committed
358
      !
359
360
      ! 2)  READ THE EIGENVALUES FILE
      !
Marco Govoni's avatar
Marco Govoni committed
361
      IF(.NOT.ALLOCATED(ev)) ALLOCATE(ev(n_eigen_to_get))
Marco Govoni's avatar
Marco Govoni committed
362
      IF ( mpime==root ) ev(1:nglob_to_be_read) = tmp_ev(1:nglob_to_be_read)
Marco Govoni's avatar
Marco Govoni committed
363
364
      CALL mp_bcast( ev, root, world_comm )
      !
365
366
367
368
      IF(.NOT.ALLOCATED(eigenpot_filename)) ALLOCATE( CHARACTER(LEN=25) :: eigenpot_filename(n_eigen_to_get) )
      DO ielement = 1, n_eigen_to_get
         CALL mp_bcast(eigenpot_filename(ielement),root,world_comm)
      ENDDO
Govoni's avatar
Govoni committed
369
      !
Marco Govoni's avatar
Marco Govoni committed
370
371
372
      ! 3)  READ THE EIGENVECTOR FILES
      !
      IF(.NOT.ALLOCATED(dvg)) THEN
373
         ALLOCATE(dvg(npwqx,pert%nlocx))
Marco Govoni's avatar
Marco Govoni committed
374
375
376
377
378
379
380
381
382
         dvg = 0._DP
      ENDIF
      !
      DO local_j=1,pert%nloc
         !
         ! local -> global
         !
         global_j = pert%l2g(local_j)
         IF(global_j>n_eigen_to_get) CYCLE
383
384
385
         !
         fname = TRIM(ADJUSTL(wstat_save_dir)) // "/"// TRIM(ADJUSTL(eigenpot_filename(global_j)))
         CALL pdep_read_G_and_distribute(fname,dvg(:,local_j),iq_)
Marco Govoni's avatar
Marco Govoni committed
386
387
388
389
390
391
392
393
394
395
396
397
         !
      ENDDO
      !
      ! MPI BARRIER
      !
      CALL mp_barrier( world_comm )
      !
      ! TIMING
      !
      time_spent(2)=get_clock('pdep_db')
      CALL stop_clock('pdep_db')
      !
398
      IF (lprintinfo_) THEN
399
400
401
         WRITE(stdout,'(  5x," ")')
         CALL io_push_bar()
         WRITE(stdout, "(5x, 'SAVE read in ',a20)") human_readable_time(time_spent(2)-time_spent(1)) 
402
         WRITE(stdout, "(5x, 'In location : ',a)") TRIM(ADJUSTL( wstat_save_dir )) 
403
404
405
         WRITE(stdout, "(5x, 'Eigen. found : ',i12)") n_eigen_to_get
         CALL io_push_bar()
      ENDIF
Marco Govoni's avatar
Marco Govoni committed
406
      !
407
408
409
      IF(ALLOCATED(eigenpot_filename)) DEALLOCATE(eigenpot_filename)
      IF(ALLOCATED(fname)) DEALLOCATE(fname)
      !
Marco Govoni's avatar
Marco Govoni committed
410
411
412
    END SUBROUTINE
    !
END MODULE