The Elk Code
gndstulr.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2017 T. Mueller, J. K. Dewhurst, S. Sharma and E. K. U. Gross.
3 ! This file is distributed under the terms of the GNU General Public License.
4 ! See the file COPYING for license details.
5 
6 subroutine gndstulr
7 use modmain
8 use modulr
9 use modomp
10 use modmpi
11 implicit none
12 ! local variables
13 logical twrite
14 integer ik0,lp,nthd
15 integer nmix,nwork,n
16 real(8) dv
17 character(64) str
18 ! allocatable arrays
19 real(8), allocatable :: work(:)
20 complex(8), allocatable :: evecu(:,:)
21 ! no k-point reduction
23 reducek=0
24 ! initialise global variables
25 call init0
26 call init1
27 ! write the κ-points to file
28 call writekpa
29 ! write the k+κ-points to file
30 call writekpts
31 ! write the Q-points to file
32 call writeqpts
33 ! read the regular Kohn-Sham potential from file
34 call readstate
35 ! generate the first- and second-variational eigenvectors and eigenvalues for
36 ! the k+κ-point set
37 call genvsig
38 call gencore
39 call linengy
40 call genapwlofr
41 call gensocfr
42 call genevfsv
43 call occupy
44 ! initialise the ultra long-range variables
45 call initulr
46 if (task == 700) then
47 ! initialise the long-range Kohn-Sham potential and magnetic field
48  call potuinit
49 else
50 ! read in the potential and density from STATE_ULR.OUT
51  call readstulr
52 end if
53 ! initialise the external Coulomb potential
54 call vclqinit
55 ! initialise the external magnetic field if required
56 if (spinpol) call bfcqinit
57 ! size of mixing vector (complex array)
58 nmix=2*size(vsbsq)
59 ! determine the size of the mixer work array
60 nwork=-1
61 call mixerifc(mixtype,nmix,vsbsq,dv,nwork,work)
62 allocate(work(nwork))
63 ! initialise the mixer
64 iscl=0
65 call mixerifc(mixtype,nmix,vsbsq,dv,nwork,work)
66 ! set last self-consistent loop flag
67 tlast=.false.
68 ! begin the self-consistent loop
69 if (mp_mpi) then
70 ! open ULR_INFO.OUT file
71  open(60,file='ULR_INFO.OUT',form='FORMATTED')
72 ! open RMSDVS.OUT
73  open(65,file='RMSDVS.OUT',form='FORMATTED')
74  call writeinfou(60)
75  call writebox(60,"Self-consistent loop started")
76 end if
77 do iscl=1,maxscl
78  if (mp_mpi) then
79  write(str,'("Loop number : ",I0)') iscl
80  call writebox(60,trim(str))
81  end if
82  if (iscl >= maxscl) then
83  if (mp_mpi) then
84  write(60,*)
85  write(60,'("Reached self-consistent loops maximum")')
86  end if
87  write(*,*)
88  write(*,'("Warning(gndstulr): failed to reach self-consistency after ",I0,&
89  &" loops")') iscl
90  tlast=.true.
91  end if
92 ! reset the OpenMP thread variables
93  call omp_reset
94 ! apply required local operations to the potential and magnetic field
95  call vblocalu
96 ! zero the density and magnetisation
97  rhormt(:,:,:)=0.d0; rhorir(:,:)=0.d0
98  magrmt(:,:,:,:)=0.d0; magrir(:,:,:)=0.d0
99 ! loop over original k-points
100  call holdthd(nkpt0/np_mpi,nthd)
101 !$OMP PARALLEL DEFAULT(SHARED) &
102 !$OMP PRIVATE(evecu) &
103 !$OMP REDUCTION(+:rhormt,rhorir,magrmt,magrir) &
104 !$OMP NUM_THREADS(nthd)
105  allocate(evecu(nstulr,nstulr))
106 !$OMP DO SCHEDULE(DYNAMIC)
107  do ik0=1,nkpt0
108 ! distribute among MPI processes
109  if (mod(ik0-1,np_mpi) /= lp_mpi) cycle
110 ! solve the ultra long-range eigenvalue equation
111  call eveqnulr(ik0,evecu)
112 ! write the eigenvalues to file
113  call putevalu(ik0)
114 ! add to the density, magnetisation and current
115  call rhomaguk(ik0,evecu,rhormt,rhorir,magrmt,magrir)
116  end do
117 !$OMP END DO
118  deallocate(evecu)
119 !$OMP END PARALLEL
120  call freethd(nthd)
121  if (np_mpi > 1) then
122 ! broadcast eigenvalue array to every process
123  do ik0=1,nkpt0
124  lp=mod(ik0-1,np_mpi)
125  call mpi_bcast(evalu(:,ik0),nstulr,mpi_double_precision,lp,mpicom,ierror)
126  end do
127 ! add densities from each process and redistribute
128  n=size(rhormt)
129  call mpi_allreduce(mpi_in_place,rhormt,n,mpi_double_precision,mpi_sum, &
130  mpicom,ierror)
131  n=size(rhorir)
132  call mpi_allreduce(mpi_in_place,rhorir,n,mpi_double_precision,mpi_sum, &
133  mpicom,ierror)
134  if (spinpol) then
135  n=size(magrmt)
136  call mpi_allreduce(mpi_in_place,magrmt,n,mpi_double_precision,mpi_sum, &
137  mpicom,ierror)
138  n=size(magrir)
139  call mpi_allreduce(mpi_in_place,magrir,n,mpi_double_precision,mpi_sum, &
140  mpicom,ierror)
141  end if
142  end if
143 ! find the occupation numbers and Fermi energy
144  call occupyulr
145 ! synchronise MPI processes
146  call mpi_barrier(mpicom,ierror)
147 ! add the core density
148  call rhocoreu
149 ! perform partial Fourier transform to Q-space
150  call rhomagq
151 ! determine the muffin-tin and interstitial charges and moments
152  call chargeu
153  call momentu
154 ! compute the ultra long-range Kohn-Sham potential
155  call potksu
156 ! mix the old potential and field with the new
157  call mixerifc(mixtype,nmix,vsbsq,dv,nwork,work)
158 ! multiply the RMS change in potential by the number of Q-points
159  dv=dv*dble(nfqrz)
160 ! calculate and add the fixed spin moment effective field (after mixing)
161  call bfieldfsm
162  call addbfsmu
163 ! compute the energy components
164  call energyulr
165  if (mp_mpi) then
166 ! write the eigenvalues to file
167  call writeevalu
168 ! write the occupation numbers to file
169  do ik0=1,nkpt0
170  call putocculr(ik0)
171  end do
172 ! output energy components
173  call writeengyu(60)
174 ! output charges
175  call writechg(60)
176 ! write muffin-tin, interstitial and total charges for each R-vector
177  call writechgru
178 ! write the charges for each Q-vector
179  call writechgqu
180  if (spinpol) then
181 ! output moments
182  call writemom(60)
183 ! write muffin-tin, interstitial and total moments for each R-vector
184  call writemomru
185 ! write the moments for each Q-vector
186  call writemomqu
187  end if
188 ! output effective fields for fixed spin moment calculations
189  if (fsmtype /= 0) call writefsm(60)
190 ! check for existence of the WRITE file
191  call checkwrite(twrite)
192 ! check self-consistent loop number modulo nwrite
193  if (nwrite >= 1) then
194  if (mod(iscl,nwrite) == 0) twrite=.true.
195  end if
196 ! write STATE_ULR.OUT file if required
197  if (twrite) then
198  call writestulr
199  write(60,*)
200  write(60,'("Wrote STATE_ULR.OUT")')
201  end if
202  end if
203 ! exit self-consistent loop if required
204  if (tlast) goto 10
205 ! check for convergence
206  if (iscl >= 2) then
207  if (mp_mpi) then
208  write(60,*)
209  write(60,'("RMS change in Kohn-Sham potential (target) : ",G18.10," (",&
210  &G18.10,")")') dv,epspot
211  flush(60)
212  write(65,'(G18.10)') dv
213  flush(65)
214  end if
215  if (dv < epspot) then
216  if (mp_mpi) then
217  write(60,*)
218  write(60,'("Convergence targets achieved")')
219  end if
220  tlast=.true.
221  end if
222  end if
223 ! check for STOP file
224  call checkstop
225  if (tstop) tlast=.true.
226 ! broadcast tlast from master process to all other processes
227  call mpi_bcast(tlast,1,mpi_logical,0,mpicom,ierror)
228 ! reset the OpenMP thread variables
229  call omp_reset
230 end do
231 10 continue
232 if (mp_mpi) then
233 ! output timing information
234  write(60,*)
235  write(60,'("Timings (CPU seconds) :")')
236  write(60,'(" Hamiltonian matrix set up",T40,": ",F12.2)') timemat
237  write(60,'(" eigenvalue equation",T40,": ",F12.2)') timesv
238  write(60,'(" charge density calculation",T40,": ",F12.2)') timerho
239  write(60,'(" potential calculation",T40,": ",F12.2)') timepot
240  call writebox(60,"Self-consistent loop stopped")
241  if (maxscl > 1) then
242  call writestulr
243  write(60,*)
244  write(60,'("Wrote STATE_ULR.OUT")')
245  end if
246 ! close the ULR_INFO.OUT file
247  close(60)
248 ! close the RMSDVS.OUT file
249  close(65)
250 end if
251 deallocate(work)
252 ! restore original parameters
254 ! synchronise MPI processes
255 call mpi_barrier(mpicom,ierror)
256 end subroutine
257 
subroutine readstulr
Definition: readstulr.f90:7
subroutine potuinit
Definition: potuinit.f90:7
subroutine genevfsv
Definition: genevfsv.f90:7
integer mixtype
Definition: modmain.f90:698
subroutine gndstulr
Definition: gndstulr.f90:7
integer task
Definition: modmain.f90:1299
logical mp_mpi
Definition: modmpi.f90:17
subroutine occupy
Definition: occupy.f90:10
logical spinpol
Definition: modmain.f90:230
subroutine addbfsmu
Definition: addbfsmu.f90:7
integer nstulr
Definition: modulr.f90:97
subroutine writechgru
Definition: writechgru.f90:7
integer reducek0
Definition: modmain.f90:458
subroutine writekpts
Definition: writekpts.f90:10
subroutine bfcqinit
Definition: bfcqinit.f90:7
integer iscl
Definition: modmain.f90:1053
subroutine gencore
Definition: gencore.f90:10
Definition: modomp.f90:6
logical tstop
Definition: modmain.f90:1057
subroutine writeinfou(fnum)
Definition: writeinfou.f90:7
integer nkpt0
Definition: modulr.f90:18
real(8) timemat
Definition: modmain.f90:1217
subroutine momentu
Definition: momentu.f90:7
subroutine genvsig
Definition: genvsig.f90:10
subroutine genapwlofr
Definition: genapwlofr.f90:7
subroutine checkstop
Definition: checkstop.f90:7
subroutine putocculr(ik0)
Definition: putocculr.f90:7
subroutine gensocfr
Definition: gensocfr.f90:10
integer np_mpi
Definition: modmpi.f90:13
real(8) timerho
Definition: modmain.f90:1223
subroutine writeevalu
Definition: writeevalu.f90:7
subroutine chargeu
Definition: chargeu.f90:7
subroutine linengy
Definition: linengy.f90:10
subroutine occupyulr
Definition: occupyulr.f90:7
subroutine mixerifc(mtype, n, v, dv, nwork, work)
Definition: mixerifc.f90:7
real(8) timepot
Definition: modmain.f90:1225
subroutine rhocoreu
Definition: rhocoreu.f90:7
logical tlast
Definition: modmain.f90:1055
subroutine writefsm(fnum)
Definition: writefsm.f90:7
subroutine checkwrite(twrite)
Definition: checkwrite.f90:7
real(8), dimension(:,:), allocatable rhorir
Definition: modulr.f90:52
real(8), dimension(:,:,:), allocatable rhormt
Definition: modulr.f90:52
subroutine vclqinit
Definition: vclqinit.f90:7
subroutine bfieldfsm
Definition: bfieldfsm.f90:10
subroutine writeengyu(fnum)
Definition: writeengyu.f90:7
subroutine writestulr
Definition: writestulr.f90:7
subroutine rhomagq
Definition: rhomagq.f90:7
subroutine init1
Definition: init1.f90:10
subroutine potksu
Definition: potksu.f90:7
subroutine writekpa
Definition: writekpa.f90:7
integer nwrite
Definition: modmain.f90:1061
integer nfqrz
Definition: modmain.f90:542
Definition: modmpi.f90:6
subroutine writechg(fnum)
Definition: writechg.f90:7
real(8) epspot
Definition: modmain.f90:1063
subroutine writebox(fnum, str)
Definition: writebox.f90:7
subroutine readstate
Definition: readstate.f90:10
subroutine omp_reset
Definition: modomp.f90:71
integer lp_mpi
Definition: modmpi.f90:15
subroutine freethd(nthd)
Definition: modomp.f90:112
subroutine holdthd(nloop, nthd)
Definition: modomp.f90:78
real(8), dimension(:,:,:,:), allocatable magrmt
Definition: modulr.f90:53
subroutine putevalu(ik0)
Definition: putevalu.f90:7
real(8) timesv
Definition: modmain.f90:1221
subroutine vblocalu
Definition: vblocalu.f90:7
integer reducek
Definition: modmain.f90:458
subroutine init0
Definition: init0.f90:10
real(8), dimension(:,:,:), allocatable magrir
Definition: modulr.f90:53
subroutine rhomaguk(ik0, evecu, rhormt_, rhorir_, magrmt_, magrir_)
Definition: rhomaguk.f90:7
Definition: modulr.f90:6
subroutine eveqnulr(ik0, evecu)
Definition: eveqnulr.f90:7
subroutine writechgqu
Definition: writechgqu.f90:7
complex(8), dimension(:), allocatable, target vsbsq
Definition: modulr.f90:85
real(8), dimension(:,:), allocatable evalu
Definition: modulr.f90:99
subroutine writemom(fnum)
Definition: writemom.f90:7
integer maxscl
Definition: modmain.f90:1051
integer mpicom
Definition: modmpi.f90:11
subroutine initulr
Definition: initulr.f90:7
subroutine energyulr
Definition: energyulr.f90:7
subroutine writemomru
Definition: writemomru.f90:7
integer fsmtype
Definition: modmain.f90:253
subroutine writemomqu
Definition: writemomqu.f90:7
integer ierror
Definition: modmpi.f90:19
subroutine writeqpts
Definition: writeqpts.f90:7