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