Line data Source code
1 : !!****m* ABINIT/m_rttddft_propagators
2 : !! NAME
3 : !! m_rttddft_propagators
4 : !!
5 : !! FUNCTION
6 : !! Contains various propagators for the KS orbitals
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2021-2026 ABINIT group (FB)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_rttddft_propagators
23 :
24 : use defs_basis
25 : use defs_abitypes, only: MPI_type
26 : use defs_datatypes, only: pseudopotential_type
27 :
28 : use m_bandfft_kpt, only: bandfft_kpt, bandfft_kpt_type, &
29 : & bandfft_kpt_set_ikpt, &
30 : & prep_bandfft_tabs
31 : use m_dtset, only: dataset_type
32 : use m_energies, only: energies_type
33 : use m_errors, only: msg_hndl
34 : use m_gemm_nonlop_projectors, only: set_gemm_nonlop_ikpt
35 : use m_hamiltonian, only: gs_hamiltonian_type, gspot_transgrid_and_pack
36 : use m_invovl, only: make_invovl
37 : use m_kg, only: mkkin, mkkpg
38 : use m_mkffnl, only: mkffnl
39 : use m_mpinfo, only: proc_distrb_cycle
40 : use m_profiling_abi, only: abimem_record
41 : use m_rttddft, only: rttddft_init_hamiltonian
42 : use m_rttddft_exponential, only: rttddft_exp_taylor
43 : use m_rttddft_properties, only: rttddft_calc_density, &
44 : & rttddft_calc_occ, &
45 : & rttddft_calc_kin
46 : use m_rttddft_tdks, only: tdks_type
47 : use m_specialmsg, only: wrtout
48 : use m_xmpi, only: xmpi_comm_rank, xmpi_sum, xmpi_max
49 :
50 : implicit none
51 :
52 : private
53 : !!***
54 :
55 : public :: rttddft_propagator_er
56 : public :: rttddft_propagator_emr
57 : !!***
58 :
59 : contains
60 : !!***
61 :
62 : !!****f* m_rttddft/rttddft_propagator_er
63 : !!
64 : !! NAME
65 : !! rttddft_propagator_er
66 : !!
67 : !! FUNCTION
68 : !! Main subroutine to propagate the KS orbitals using
69 : !! the Exponential Rule (ER) propagator.
70 : !!
71 : !! INPUTS
72 : !! dtset <type(dataset_type)> = all input variables for this dataset
73 : !! ham_k <type(gs_hamiltonian_type)> = Hamiltonian object
74 : !! istep <integer> = step number
75 : !! mpi_enreg <MPI_type> = MPI-parallelisation information
76 : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
77 : !! tdks <type(tdks_type)> = the tdks object to initialize
78 : !! calc_properties <logical> = logical governing the computation of
79 : !! some properties (energies, occupations, eigenvalues..)
80 : !!
81 : !! NOTES
82 : !! Other propagators such as the Exponential Midpoint Rule (EMR)
83 : !! should usually be prefered over this one since the ER propagator
84 : !! alone violates time reversal symmetry. Using this propagator with
85 : !! the exponential approximated by Taylor expansion of order 1 leads
86 : !! to the famous Euler method which is fast and simple but unstable
87 : !! and thus insufficient for RT-TDDFT.
88 : !!
89 : !! SOURCE
90 1755 : subroutine rttddft_propagator_er(dtset, istep, mpi_enreg, psps, tdks, calc_properties)
91 :
92 : !Arguments ------------------------------------
93 : !scalars
94 : integer, intent(in) :: istep
95 : logical, optional, intent(in) :: calc_properties
96 : type(dataset_type), intent(inout) :: dtset
97 : type(MPI_type), intent(inout) :: mpi_enreg
98 : type(pseudopotential_type), intent(inout) :: psps
99 : type(tdks_type), target, intent(inout) :: tdks
100 :
101 : !Local variables-------------------------------
102 : !scalars
103 : integer :: bdtot_index
104 : integer :: calc_forces
105 : integer :: dimffnl
106 : integer :: iband
107 : integer :: ibg, icg
108 : integer :: ider, idir
109 : integer :: ierr, ilm
110 : integer :: ikpt, ikpt_loc, ikg
111 : integer :: isppol
112 : integer :: istwf_k
113 : integer :: me_distrb
114 : integer :: me_bandfft
115 : integer :: my_ikpt, my_nspinor
116 : integer :: nband_k, nband_k_mem
117 : integer :: npw_k, nkpg
118 : integer :: shift
119 : integer :: spaceComm_distrb
120 : integer :: n4, n5, n6
121 : logical :: with_vxctau
122 : logical :: lcalc_properties
123 : type(energies_type) :: energies
124 : type(bandfft_kpt_type),pointer :: my_bandfft_kpt => null()
125 1755 : type(gs_hamiltonian_type) :: ham_k
126 : !arrays
127 1755 : integer, allocatable :: kg_k(:,:)
128 : real(dp), pointer :: cg(:,:) => null()
129 : real(dp), pointer :: cg0(:,:) => null()
130 1755 : real(dp), allocatable :: enl(:)
131 : real(dp), pointer :: eig(:) => null()
132 1755 : real(dp), allocatable :: ffnl(:,:,:,:)
133 1755 : real(dp), allocatable :: kpg_k(:,:)
134 : real(dp) :: kpoint(3)
135 : real(dp) :: kpa(3)
136 1755 : real(dp), allocatable :: kinpw(:)
137 : real(dp), pointer :: occ(:) => null()
138 : real(dp), pointer :: occ0(:) => null()
139 1755 : real(dp), allocatable :: ph3d(:,:,:)
140 1755 : real(dp), allocatable :: vlocal(:,:,:,:)
141 1755 : real(dp), allocatable :: vxctaulocal(:,:,:,:,:)
142 1755 : real(dp), allocatable :: ylm_k(:,:)
143 : logical :: lproperties(4)
144 :
145 : ! ***********************************************************************
146 :
147 : !Init MPI
148 1755 : spaceComm_distrb=mpi_enreg%comm_cell
149 960 : if (mpi_enreg%paral_kgb==1) spaceComm_distrb=mpi_enreg%comm_kpt
150 1755 : me_distrb=xmpi_comm_rank(spaceComm_distrb)
151 :
152 : !Do we calculate properties?
153 : !Governed by lproperties:
154 : ! lproperties(1) = compute energy contributions (kinetic)
155 : ! lproperties(2) = NL energy contribution in NC case
156 : ! lproperties(3) = eigenvalues
157 : ! lproperties(4) = occupations
158 1755 : lproperties(:) = .false.
159 1755 : lcalc_properties = .false.
160 1755 : if (present(calc_properties)) then
161 1725 : lcalc_properties = calc_properties
162 1725 : if (lcalc_properties) then
163 : !compute energy contributions
164 1725 : lproperties(1) = .true.
165 : !Init to zero different energies
166 1725 : call energies%init()
167 1725 : energies%entropy_ks=tdks%energies%entropy_ks
168 1725 : energies%e_corepsp=tdks%energies%e_corepsp
169 1725 : energies%e_ewald=tdks%energies%e_ewald
170 : !including NL part in NC case?
171 1725 : if (dtset%usepaw == 0) then
172 200 : lproperties(2) = .true.
173 600 : ABI_MALLOC(enl,(mpi_enreg%bandpp))
174 : else
175 1525 : ABI_MALLOC(enl,(0))
176 : end if
177 : !other properties
178 : ! eigenvalues
179 1725 : if (dtset%prteig /= 0 .or. dtset%prtdos /= 0) then
180 0 : if (mod(istep-1,dtset%td_prtstr) == 0) then
181 0 : lproperties(3) = .true.
182 0 : tdks%eigen(:) = zero
183 : end if
184 : end if
185 : ! occupations
186 1725 : lproperties(4) = .true.
187 395485 : tdks%occ(:) = zero
188 : end if
189 : end if
190 :
191 : !Set "vtrial" and initialize the Hamiltonian
192 1755 : call rttddft_init_hamiltonian(dtset,energies,ham_k,istep,mpi_enreg,psps,tdks)
193 :
194 1755 : my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
195 1755 : n4=dtset%ngfft(4); n5=dtset%ngfft(5); n6=dtset%ngfft(6)
196 10530 : ABI_MALLOC(vlocal,(n4,n5,n6,ham_k%nvloc))
197 7020 : with_vxctau=(size(tdks%vxctau)>0)
198 1755 : if(with_vxctau) then
199 0 : ABI_MALLOC(vxctaulocal,(n4,n5,n6,ham_k%nvloc,4))
200 : end if
201 1755 : if (dtset%ionmov/=0) then
202 : calc_forces=1
203 : else
204 1755 : calc_forces=0
205 : end if
206 :
207 : !FB: @MT Needed?
208 : !has_vectornd = (with_vectornd .EQ. 1)
209 : !if(has_vectornd) then
210 : ! ABI_MALLOC(vectornd_pac,(n4,n5,n6,ham_k%nvloc,3))
211 : ! vectornd_pac=zero
212 : !end if
213 :
214 1755 : icg=0; ibg=0
215 1755 : bdtot_index=0
216 :
217 : !*** LOOP OVER SPINS
218 3510 : do isppol=1,dtset%nsppol
219 :
220 1755 : ikpt_loc=0
221 1755 : ikg=0
222 :
223 : ! Set up local potential vlocal on the coarse FFT mesh from vtrial taking into account the spin.
224 : ! Also, continue to initialize the Hamiltonian.
225 : call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, tdks%nfftf, &
226 1755 : & dtset%nspden, ham_k%nvloc, 1, tdks%pawfgr, mpi_enreg, tdks%vtrial, vlocal)
227 1755 : call ham_k%load_spin(isppol, vlocal=vlocal, with_nonlocal=.true.)
228 :
229 1755 : if (with_vxctau) then
230 : call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, tdks%nfftf, &
231 0 : & dtset%nspden, ham_k%nvloc, 4, tdks%pawfgr, mpi_enreg, tdks%vxctau, vxctaulocal)
232 0 : call ham_k%load_spin(isppol, vxctaulocal=vxctaulocal)
233 : end if
234 :
235 : !FB: @MT Needed?
236 : ! ! if vectornd is present, set it up for addition to ham_k similarly to how it's done for
237 : ! ! vtrial. Note that it must be done for the three Cartesian directions. Also, the following
238 : ! ! code assumes explicitly and implicitly that nvloc = 1. This should eventually be generalized.
239 : ! if(has_vectornd) then
240 : ! do idir = 1, 3
241 : ! ABI_MALLOC(cgrvtrial,(dtset%nfft,dtset%nspden))
242 : ! call transgrid(1,mpi_enreg,dtset%nspden,-1,0,0,dtset%paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vectornd(:,idir))
243 : ! call fftpac(isppol,mpi_enreg,dtset%nspden,n1,n2,n3,n4,n5,n6,dtset%ngfft,cgrvtrial,vectornd_pac(:,:,:,1,idir),2)
244 : ! ABI_FREE(cgrvtrial)
245 : ! end do
246 : ! call ham_k%load_spin(isppol, vectornd=vectornd_pac)
247 : ! end if
248 :
249 : !*** BIG FAT k POINT LOOP
250 1755 : ikpt = 0
251 50570 : do while (ikpt_loc < dtset%nkpt)
252 :
253 47060 : ikpt_loc = ikpt_loc + 1
254 47060 : ikpt = ikpt_loc
255 47060 : my_ikpt = mpi_enreg%my_kpttab(ikpt)
256 :
257 47060 : nband_k=dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
258 47060 : if (mpi_enreg%paral_kgb==1) then
259 26240 : nband_k_mem=mpi_enreg%bandpp
260 : else
261 : nband_k_mem=nband_k
262 : end if
263 47060 : istwf_k=dtset%istwfk(ikpt)
264 47060 : npw_k=tdks%npwarr(ikpt)
265 :
266 47060 : if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_distrb)) then
267 19680 : bdtot_index=bdtot_index+nband_k
268 19680 : cycle
269 : end if
270 :
271 27380 : if (mpi_enreg%paral_kgb==1) my_bandfft_kpt => bandfft_kpt(my_ikpt)
272 27380 : call bandfft_kpt_set_ikpt(ikpt,mpi_enreg)
273 :
274 82140 : ABI_MALLOC(kg_k,(3,npw_k))
275 109520 : ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang*psps%useylm))
276 22474460 : kg_k(:,1:npw_k)=tdks%kg(:,1+ikg:npw_k+ikg)
277 27380 : if (psps%useylm==1) then
278 136300 : do ilm=1,psps%mpsang*psps%mpsang
279 21448840 : ylm_k(1:npw_k,ilm)=tdks%ylm(1+ikg:npw_k+ikg,ilm)
280 : end do
281 : end if
282 :
283 : !** Set up the remaining k-dependent part of the Hamiltonian
284 109520 : kpoint(:)=dtset%kptns(:,ikpt) !k-point
285 109520 : kpa(:)=tdks%tdef%kpa(:,ikpt) !k+A
286 :
287 : ! Kinetic energy
288 82140 : ABI_MALLOC(kinpw,(npw_k))
289 27380 : call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,tdks%gmet,kg_k,kinpw,kpoint,npw_k,0,0,tdks%tdef%vecpot_red)
290 :
291 : ! Compute (k+G) vectors (only if useylm=1)
292 27380 : nkpg=3*calc_forces*dtset%nloalg(3)
293 109520 : ABI_MALLOC(kpg_k,(npw_k,nkpg))
294 : ! Compute nonlocal form factors ffnl at all (k+G):
295 27380 : ider=0;idir=0;dimffnl=1
296 136900 : ABI_MALLOC(ffnl,(npw_k,dimffnl,psps%lmnmax,psps%ntypat))
297 27380 : if (mpi_enreg%paral_kgb/=1 .or. istep<=tdks%first_step .or. tdks%tdef%ef_type/=0) then
298 27236 : if (nkpg > 0) call mkkpg(kg_k,kpg_k,kpa,nkpg,npw_k)
299 : call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl,psps%ffspl,tdks%gmet,tdks%gprimd, &
300 : & ider,idir,psps%indlmn,kg_k,kpg_k,kpa,psps%lmnmax,psps%lnmax, &
301 : & psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,psps%ntypat,psps%pspso, &
302 27236 : & psps%qgrid_ff,tdks%rmet,psps%usepaw,psps%useylm,ylm_k,tdks%ylmgr)
303 : end if
304 :
305 : !** Load k-dependent part in the Hamiltonian datastructure
306 : !** - Compute 3D phase factors
307 : !** - Prepare various tabs in case of band-FFT parallelism
308 : !** - Load k-dependent quantities in the Hamiltonian
309 109520 : ABI_MALLOC(ph3d,(2,npw_k,ham_k%matblk))
310 : call ham_k%load_k(kpt_k=kpa,istwf_k=istwf_k,npw_k=npw_k,kinpw_k=kinpw,kg_k=kg_k,kpg_k=kpg_k, &
311 27380 : & ffnl_k=ffnl,ph3d_k=ph3d,compute_ph3d=.true.,compute_gbound=.true.)
312 :
313 : !** Load band-FFT tabs (transposed k-dependent arrays)
314 27380 : if (mpi_enreg%paral_kgb==1) then
315 6560 : if (istep<=tdks%first_step .or. tdks%tdef%ef_type/=0) then
316 6416 : call prep_bandfft_tabs(ham_k,ikpt,dtset%mkmem,mpi_enreg)
317 : end if
318 : call ham_k%load_k(npw_fft_k=my_bandfft_kpt%ndatarecv, &
319 : & gbound_k =my_bandfft_kpt%gbound, &
320 : & kinpw_k =my_bandfft_kpt%kinpw_gather, &
321 : & kg_k =my_bandfft_kpt%kg_k_gather, &
322 : & kpg_k =my_bandfft_kpt%kpg_k_gather, &
323 : & ffnl_k =my_bandfft_kpt%ffnl_gather, &
324 6560 : & ph3d_k =my_bandfft_kpt%ph3d_gather)
325 : end if
326 :
327 : !** Build inverse of overlap matrix
328 27380 : if(psps%usepaw == 1 .and. (istep <= tdks%first_step .or. tdks%tdef%ef_type/=0)) then
329 16164 : call make_invovl(ham_k,dimffnl,ffnl,ph3d,mpi_enreg)
330 : end if
331 :
332 : ! Setup gemm_nonlop
333 27380 : if (tdks%gemm_nonlop_use_gemm) then
334 : call set_gemm_nonlop_ikpt(my_ikpt,ham_k%npw_fft_k,ham_k%istwf_k,ham_k%indlmn,&
335 0 : & ham_k%ntypat,ham_k%nattyp,ham_k%gpu_option)
336 : end if
337 :
338 : !** Compute the exp[-i(S^{-1})H]*cg using Taylor expansion to approximate the exponential
339 27380 : cg => tdks%cg(:,icg+1:icg+nband_k*npw_k*my_nspinor)
340 : ! Compute properties "on-the-fly" if required
341 27380 : if (lcalc_properties) then
342 27260 : cg0 => tdks%cg0(:,icg+1:icg+nband_k*npw_k*my_nspinor)
343 27260 : occ => tdks%occ(bdtot_index+1:bdtot_index+nband_k)
344 27260 : occ0 => tdks%occ0(bdtot_index+1:bdtot_index+nband_k)
345 27260 : if (dtset%paral_kgb /= 1) then
346 : shift = bdtot_index
347 : else
348 6560 : me_bandfft = xmpi_comm_rank(mpi_enreg%comm_band)
349 6560 : shift = bdtot_index+me_bandfft*mpi_enreg%bandpp
350 : end if
351 : ! kinetic energy
352 27260 : if (lproperties(1)) then
353 : call rttddft_calc_kin(energies%e_kinetic,cg,dtset,ham_k,nband_k,npw_k,my_nspinor, &
354 27260 : & occ0,dtset%wtk(ikpt),mpi_enreg,my_bandfft_kpt)
355 : end if
356 : ! for eigenvalues
357 27260 : if (lproperties(3)) then
358 0 : eig => tdks%eigen(1+shift:nband_k_mem+shift)
359 : end if
360 : ! occupations
361 27260 : if (lproperties(4)) then
362 : !computed at istep-1 like energies and eigenvalues
363 : call rttddft_calc_occ(cg,cg0,dtset,ham_k,ikpt,ibg,isppol,mpi_enreg, &
364 27260 : & nband_k,npw_k,my_nspinor,occ,occ0,tdks)
365 : end if
366 :
367 : !Propagate cg and compute the requested properties
368 27260 : call rttddft_exp_taylor(cg,dtset,ham_k,mpi_enreg,nband_k,npw_k,my_nspinor,enl=enl,eig=eig)
369 :
370 : !Finish computing NL PSP part for NC PSP
371 27260 : if (lproperties(2)) then
372 6080 : do iband = 1, mpi_enreg%bandpp
373 6080 : energies%e_nlpsp_vfock=energies%e_nlpsp_vfock+dtset%wtk(ikpt)*tdks%occ0(shift+iband)*enl(iband)
374 : end do
375 : end if
376 : else
377 : !Propagate cg only
378 120 : call rttddft_exp_taylor(cg,dtset,ham_k,mpi_enreg,nband_k,npw_k,my_nspinor)
379 : end if
380 :
381 27380 : ABI_FREE(kg_k)
382 27380 : ABI_FREE(ylm_k)
383 27380 : ABI_FREE(kpg_k)
384 27380 : ABI_FREE(kinpw)
385 27380 : ABI_FREE(ffnl)
386 27380 : ABI_FREE(ph3d)
387 :
388 27380 : bdtot_index = bdtot_index+nband_k
389 :
390 : !** Also shift array memory if dtset%mkmem/=0
391 29135 : if (dtset%mkmem/=0) then
392 27380 : ibg=ibg+nband_k_mem
393 27380 : icg=icg+npw_k*my_nspinor*nband_k
394 27380 : ikg=ikg+npw_k
395 : end if
396 :
397 : end do !nkpt
398 :
399 : end do !nsppol
400 :
401 : ! Free memory
402 1755 : ABI_FREE(vlocal)
403 1755 : if(dtset%usekden/=0) then
404 0 : ABI_FREE(vxctaulocal)
405 : end if
406 1755 : call ham_k%free()
407 1755 : if (allocated(enl)) then
408 1725 : ABI_FREE(enl)
409 : end if
410 :
411 : !Keep the computed energies in memory
412 1755 : if (lcalc_properties) then
413 1725 : call xmpi_sum(energies%e_kinetic,mpi_enreg%comm_kptband,ierr)
414 1725 : call xmpi_sum(energies%e_nlpsp_vfock,mpi_enreg%comm_kptband,ierr)
415 1725 : call energies%copy(tdks%energies)
416 1725 : if (lproperties(3)) call xmpi_sum(tdks%eigen,mpi_enreg%comm_kptband,ierr)
417 1725 : if (lproperties(4)) call xmpi_sum(tdks%occ,mpi_enreg%comm_kpt,ierr)
418 : end if
419 :
420 3510 : end subroutine rttddft_propagator_er
421 : !!***
422 :
423 : !!****f* m_rttddft/rttddft_propagator_emr
424 : !!
425 : !! NAME
426 : !! rttddft_propagator_emr
427 : !!
428 : !! FUNCTION
429 : !! Main subroutine to propagate the KS orbitals using
430 : !! the Exponential Midpoint Rule (EMR) propagator
431 : !!
432 : !! INPUTS
433 : !! dtset <type(dataset_type)>=all input variables for this dataset
434 : !! ham_k <type(gs_hamiltonian_type)> = Hamiltonian object
435 : !! istep <integer> = step number
436 : !! mpi_enreg <MPI_type> = MPI-parallelisation information
437 : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
438 : !! tdks <type(tdks_type)> = the tdks object to initialize
439 : !!
440 : !! OUTPUT
441 : !!
442 : !! NOTES
443 : !! This propagator is time reversible
444 : !! (if H(t+dt/2) and the exponential are computed exactly).
445 : !!
446 : !! SOURCE
447 20 : subroutine rttddft_propagator_emr(dtset, istep, mpi_enreg, psps, tdks)
448 :
449 : !Arguments ------------------------------------
450 : !scalars
451 : integer, intent(in) :: istep
452 : type(dataset_type), intent(inout) :: dtset
453 : type(MPI_type), intent(inout) :: mpi_enreg
454 : type(pseudopotential_type), intent(inout) :: psps
455 : type(tdks_type), intent(inout) :: tdks
456 :
457 : !Local variables-------------------------------
458 : integer :: me
459 : !scalars
460 : character(len=500) :: msg
461 : integer :: ics
462 : integer :: ierr
463 : logical :: lconv
464 : !arrays
465 40 : real(dp) :: cg(SIZE(tdks%cg(:,1)),SIZE(tdks%cg(1,:)))
466 40 : real(dp) :: diff(SIZE(tdks%cg(:,1)),SIZE(tdks%cg(1,:)))
467 : real(dp) :: max_diff(2)
468 :
469 : ! ***********************************************************************
470 :
471 5276180 : cg(:,:) = tdks%cg(:,:) !Psi(t)
472 :
473 : !** Predictor step
474 : ! predict psi(t+dt) using ER propagator
475 20 : call rttddft_propagator_er(dtset,istep,mpi_enreg,psps,tdks,calc_properties=.true.)
476 : ! for convergence check
477 5276180 : diff = tdks%cg
478 : ! estimate psi(t+dt/2) = (psi(t)+psi(t+dt))/2
479 5276180 : tdks%cg(:,:) = 0.5_dp*(tdks%cg(:,:)+cg(:,:))
480 : ! update electric field and vector potential to t+dt/2
481 : ! We decide here not to update the induced vector potential to t+dt/2 for simplicity
482 : call tdks%tdef%update(dtset,mpi_enreg,(istep-0.5_dp)*tdks%dt,tdks%rprimd,tdks%gprimd,tdks%kg, &
483 20 : & psps%mpsang,tdks%npwarr,tdks%ylm,tdks%ylmgr,tdks%current,update_vecpot_ind=.false.)
484 : ! calc associated density at t+dt/2
485 20 : call rttddft_calc_density(dtset,mpi_enreg,psps,tdks)
486 : ! go back to time t ..
487 5276180 : tdks%cg(:,:) = cg(:,:)
488 : ! .. and evolve psi(t) using the EMR propagator with the estimated density at t+dt/2
489 20 : call rttddft_propagator_er(dtset,istep,mpi_enreg,psps,tdks)
490 :
491 : ! check convergence
492 5276180 : diff = abs(diff-tdks%cg)
493 20 : me = xmpi_comm_rank(mpi_enreg%comm_world)
494 1758760 : call xmpi_max(maxval(diff(1,:)),max_diff(1),mpi_enreg%comm_world,ierr)
495 1758760 : call xmpi_max(maxval(diff(2,:)),max_diff(2),mpi_enreg%comm_world,ierr)
496 20 : lconv = (max_diff(1) < dtset%td_scthr .and. max_diff(2) < dtset%td_scthr)
497 20 : ics = 0
498 20 : if (mpi_enreg%me == 0) then
499 20 : write(msg,'(a,a,i3,a,3(es8.2,1x),l1,a)') ch10, 'SC Step', ics, ' - ', max_diff(1), max_diff(2), &
500 40 : & dtset%td_scthr, lconv, ch10
501 20 : if (do_write_log) call wrtout(std_out,msg)
502 : end if
503 20 : if (.not. lconv) then
504 : !** Corrector steps
505 10 : do ics = 1, dtset%td_scnmax
506 : ! for convergence check
507 1451530 : diff = tdks%cg
508 : ! estimate psi(t+dt/2) = (psi(t)+psi(t+dt))/2
509 1451530 : tdks%cg(:,:) = 0.5_dp*(tdks%cg(:,:)+cg(:,:))
510 : ! calc associated density at t+dt/2
511 10 : call rttddft_calc_density(dtset,mpi_enreg,psps,tdks)
512 : ! Go back to time t ..
513 1451530 : tdks%cg(:,:) = cg(:,:)
514 : ! .. and evolve psi(t) using estimated density at t+dt/2
515 10 : call rttddft_propagator_er(dtset,istep,mpi_enreg,psps,tdks)
516 : ! check convergence
517 1451530 : diff = abs(diff-tdks%cg)
518 10 : me = xmpi_comm_rank(mpi_enreg%comm_world)
519 483860 : call xmpi_max(maxval(diff(1,:)),max_diff(1),mpi_enreg%comm_world,ierr)
520 483860 : call xmpi_max(maxval(diff(2,:)),max_diff(2),mpi_enreg%comm_world,ierr)
521 10 : lconv = (max_diff(1) < dtset%td_scthr .and. max_diff(2) < dtset%td_scthr)
522 10 : if (mpi_enreg%me == 0) then
523 10 : write(msg,'(a,a,i3,a,3(es8.2,1x),l1,a)') ch10, 'SC Step', ics, ' - ', max_diff(1), max_diff(2), &
524 20 : & dtset%td_scthr, lconv, ch10
525 10 : if (do_write_log) call wrtout(std_out,msg)
526 : end if
527 10 : if (lconv) exit
528 : end do
529 : end if
530 :
531 20 : if (lconv) then
532 20 : write(msg,'(a,i4,a)') "Converged after ", ics, " self-consistent corrector steps"
533 20 : call wrtout(ab_out,msg)
534 20 : if (do_write_log) call wrtout(std_out,msg)
535 : else
536 0 : write(msg,'(a)') "Reached maximum number of corrector steps before convergence!"
537 0 : ABI_WARNING(msg)
538 0 : call wrtout(ab_out,msg)
539 : end if
540 :
541 20 : end subroutine rttddft_propagator_emr
542 : !!***
543 :
544 : end module m_rttddft_propagators
545 : !!***
|