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
163
164
165
166
167
168
169
170
171
172
      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 )
          CALL json%print_file( iunit )
          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()
176
         CALL json%load_file( 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 )
Marco Govoni's avatar
Marco Govoni committed
196
197
198
         CALL json%print_file( iunit )
         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()
324
325
326
327
         CALL json%load_file( filename = TRIM(ADJUSTL(wstat_save_dir)) // "/summary.json" )
         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