Branch data Line data Source code
1 : : !!****p* ABINIT/mrgscr
2 : : !! NAME
3 : : !! mrgscr
4 : : !!
5 : : !! FUNCTION
6 : : !! This code reads partial (SCR|SUSC) files for different q points creating a single file that
7 : : !! can be used to perform a sigma calculation.
8 : : !!
9 : : !! COPYRIGHT
10 : : !! Copyright (C) 2005-2026 ABINIT group (RS, MG, MS)
11 : : !! This file is distributed under the terms of the
12 : : !! GNU General Public License, see ~abinit/COPYING
13 : : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
15 : : !!
16 : : !! NOTES
17 : : !! If the number of SCR files to be merged is equal to 1, the program checks
18 : : !! the integrity of the file reporting the list of missing q-points.
19 : : !! Note that the list of required q-points depends on the k-mesh
20 : : !! used during the calculation of the WFK file. We assume indeed that the same k-mesh
21 : : !! is used during the calculation of the matrix elements of sigma.
22 : : !!
23 : : !! INPUTS
24 : : !! (Main program)
25 : : !!
26 : : !! SOURCE
27 : :
28 : : #if defined HAVE_CONFIG_H
29 : : #include "config.h"
30 : : #endif
31 : :
32 : : #include "abi_common.h"
33 : :
34 : 16 : program mrgscr
35 : :
36 : 16 : use defs_basis
37 : : use m_xmpi
38 : : use m_abicore
39 : : use m_errors
40 : : use m_nctk
41 : : use netcdf
42 : : use m_hdr
43 : : use m_crystal
44 : : use m_pawrhoij
45 : : use m_dtset
46 : :
47 : : use defs_abitypes, only : MPI_type
48 : : use m_build_info, only : abinit_version
49 : : use m_argparse, only : get_arg, get_arg_list
50 : : use m_specialmsg, only : herald
51 : : use m_time, only : timein
52 : : use m_gwdefs, only : GW_TOLQ, GW_TOLQ0, GW_Q0_DEFAULT
53 : : use m_io_tools, only : prompt, flush_unit, open_file
54 : : use m_fstrings, only : int2char4, endswith, itoa, sjoin
55 : : use m_fft_mesh, only : g2ifft
56 : : use m_fftcore, only : get_cache_kb, getng
57 : : use m_fft, only : fourdp
58 : : use m_numeric_tools, only : iseven, cspint
59 : : use m_mpinfo, only : destroy_mpi_enreg, initmpi_seq
60 : : use m_geometry, only : normv, metric
61 : : use m_gsphere, only : gsphere_t
62 : : use m_bz_mesh, only : kmesh_t
63 : : use m_vcoul, only : vcoul_t
64 : : use m_ioarr, only : read_rhor
65 : : use m_io_screening, only : read_screening, hscr_t, ioscr_qmerge, ioscr_qrecover, ioscr_wmerge, ioscr_wremove
66 : : use m_ppmodel, only : ppmodel_t, cqratio
67 : : use m_model_screening, only : remove_phase
68 : : use m_screening, only : epsm1_t
69 : : use m_wfd, only : test_charge
70 : :
71 : : implicit none
72 : :
73 : : !Local variables-------------------------------
74 : : !scalars
75 : : integer,parameter :: master=0,paral_kgb0=0,rdwr2=2,prtvol=0,cplex1=1
76 : : integer :: iomode,fform1,ifile,ierr,ii,ios,iqibz,iqf,nfiles, abimem_level
77 : : integer :: unt_dump,idx,ig1,ig2,iomega,ppmodel,npwe_asked,mqmem,io,unt_dump2
78 : : integer :: id_required,ikxc,approx_type,option_test,dim_kxcg,usexcnhat,usefinegrid
79 : : integer :: mgfft,nqlwl,nfft,igmax,comm,nq_selected,kptopt
80 : : integer :: choice,nfreq_tot,nfreqre,nfreqim,nfreqc,ifrq,imax
81 : : integer :: ig1_start,ig1_end,ig2_start,ig2_end,gmgp_idx,orig_npwe
82 : : real(dp) :: ucvol,boxcutmin,ecut,drude_plsmf,compch_fft,compch_sph
83 : : real(dp) :: nelectron_exp,freqremax,eps_diff,eps_norm,eps_ppm_norm, abimem_limit_mb
84 : : real(dp) :: value1,value2,factor,GN_drude_plsmf
85 : : real(dp) :: tcpu,tcpui,twall,twalli
86 : : real(gwp) :: phase
87 : : logical :: is_sus,is_scr,same_freqs,calc_epsilon,only_diag
88 : : character(len=1) :: ans
89 : : character(len=10) :: tagq
90 : : character(len=24) :: codename
91 : : character(len=500) :: msg
92 : : character(len=nctk_slen) :: varname
93 : : character(len=fnlen) :: fname_out,fname,fname_dump,fname_rho,prefix,fname_eigen,fname_dump2
94 : 16 : type(hdr_type) :: hdr_rhor
95 : : type(abifile_t) :: abifile
96 : : type(hscr_t),pointer :: Hscr0
97 [ + + ]: 64 : type(hscr_t),target :: Hscr_merge
98 : 16 : type(MPI_type) :: MPI_enreg
99 [ + + + + : 416 : type(kmesh_t) :: Kmesh, Qmesh
+ + + + ]
100 [ + + + + : 1008 : type(crystal_t) :: Cryst
+ + + + +
+ + + + +
+ + + + +
+ ]
101 : 16 : type(gsphere_t) :: Gsphere
102 : 16 : type(ppmodel_t) :: PPm
103 [ + + ]: 64 : type(epsm1_t) :: epsm1
104 [ + + + + : 352 : type(vcoul_t), target :: Vcp
+ + + + +
+ ]
105 [ + + + + : 2048 : type(Dataset_type) :: Dtset
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ ]
106 : : !arrays
107 : : integer :: ngfft(18)
108 : 16 : integer,allocatable :: foundq(:),freq_indx(:,:)
109 : : real(dp),parameter :: k0(3) = [zero,zero,zero]
110 : : real(dp) :: gmet(3,3),gprimd(3,3),qdiff(3),rmet(3,3),mat(3,3),qtmp(3),tsec(2)
111 : 32 : real(dp),allocatable :: qlwl(:,:),real_omega(:),rhor(:,:),rhog(:,:),nhat(:,:)
112 : 64 : real(dp),allocatable :: work(:),ftab(:),ysp(:,:),eint(:),qratio(:,:)
113 : 16 : complex(gwp),pointer :: vc_sqrt(:)
114 : 32 : complex(gwp),allocatable :: tmp_epsm1(:,:,:,:),kxcg(:,:)
115 : 16 : complex(dp),allocatable :: omega(:),em1_ppm(:),epsm1_eigen(:,:),ppm_eigen(:,:),rhoggp(:,:)
116 : 16 : character(len=fnlen),allocatable :: filenames(:)
117 : 16 : type(pawrhoij_type),allocatable :: pawrhoij(:)
118 : 16 : type(hscr_t),target,allocatable :: Hscr_file(:)
119 : : ! *************************************************************************
120 : :
121 : : ! Change communicator for I/O (mandatory!)
122 : 16 : call abi_io_redirect(new_io_comm=xmpi_world)
123 : :
124 : : ! Initialize MPI
125 : 16 : call xmpi_init()
126 : :
127 : : ! Initialize memory profiling if it is activated
128 : : ! if a full abimem.mocc report is desired, set the argument of abimem_init to "2" instead of "0"
129 : : ! note that abimem.mocc files can easily be multiple GB in size so don't use this option normally
130 [ - + ]: 16 : ABI_CHECK(get_arg("abimem-level", abimem_level, msg, default=0) == 0, msg)
131 [ - + ]: 16 : ABI_CHECK(get_arg("abimem-limit-mb", abimem_limit_mb, msg, default=20.0_dp) == 0, msg)
132 : : #ifdef HAVE_MEM_PROFILING
133 : : call abimem_init(abimem_level, limit_mb=abimem_limit_mb)
134 : : #endif
135 : :
136 : 16 : call timein(tcpui,twalli)
137 : :
138 : : ! Default for sequential use
139 : 16 : call initmpi_seq(MPI_enreg); comm = MPI_enreg%comm_world
140 : :
141 : 16 : is_sus=.FALSE.; is_scr=.FALSE.
142 : :
143 : : ! Write greetings, and read the number of files ===
144 : 16 : codename='MRGSCR'//REPEAT(' ',18)
145 : 16 : call herald(codename,abinit_version,std_out)
146 : :
147 : 16 : call prompt(' Enter the number of files to merge: ',nfiles)
148 [ - + ]: 16 : ABI_CHECK(nfiles > 0, 'nfiles must be >0')
149 : :
150 [ + - - + : 16 : ABI_MALLOC(filenames,(nfiles))
- + - + -
+ - + -
+ ]
151 [ + - - + : 96 : ABI_MALLOC(Hscr_file,(nfiles))
- + - + -
+ - + - +
+ + + + +
- - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - -
- - - - -
- - - - -
- - ]
152 : :
153 [ + + ]: 16 : if (nfiles == 1) then
154 : 4 : call prompt(' Enter the name of the file to be analyzed: ',filenames(1))
155 : 4 : write(msg,'(7a)')ch10,&
156 : 4 : ' Running single-file mode:',ch10,&
157 [ + - ]: 4 : ' Checking the integrity of file: ',TRIM(filenames(1)),ch10,&
158 : 8 : ' reporting the list of q-points that are missing. '
159 : 4 : call wrtout(std_out, msg)
160 : :
161 [ - + ]: 4 : if (nctk_try_fort_or_ncfile(filenames(1), msg) /= 0) then
162 : 0 : ABI_ERROR(msg)
163 : : end if
164 : :
165 [ + - ]: 12 : else if (nfiles > 1) then
166 : : ! Read name of files to be merged and check for existence.
167 : 12 : call prompt(' Enter the prefix for the final output file: ',fname_out)
168 : :
169 [ + + ]: 40 : do ifile=1,nfiles
170 : 28 : write(msg,'(a,i4)')' Enter the name for the partial screening file no.',ifile
171 : 28 : call prompt(msg,filenames(ifile))
172 : :
173 [ - + ]: 40 : if (nctk_try_fort_or_ncfile(filenames(ifile), msg) /= 0) then
174 : 0 : ABI_ERROR(msg)
175 : : end if
176 : : end do
177 : : end if
178 : :
179 : : ! Read the header of each file.
180 [ + + ]: 48 : do ifile=1,nfiles
181 [ + - ]: 32 : iomode = IO_MODE_FORTRAN; if (endswith(filenames(ifile), ".nc")) iomode = IO_MODE_ETSF
182 : :
183 : 32 : call Hscr_file(ifile)%from_file(filenames(ifile), fform1, comm)
184 [ - + ]: 32 : ABI_CHECK(fform1 /= 0, sjoin("fform == 0 in", filenames(ifile)))
185 : :
186 : 32 : abifile = abifile_from_fform(fform1)
187 [ - + ]: 32 : if (abifile%fform == 0) then
188 : 0 : ABI_ERROR(sjoin("Cannot find any abifile object associated to fform1:", itoa(fform1)))
189 : : end if
190 [ - + ]: 32 : if (abifile%class /= "polariz" .and. abifile%class /= "epsm1") then
191 : 0 : ABI_ERROR(sjoin('Error while reading header, fform= ',itoa(fform1)))
192 : : end if
193 : 32 : is_scr = abifile%class == "epsm1"
194 : 32 : is_sus = abifile%class == "polariz"
195 : :
196 [ + + ]: 64 : call Hscr_file(ifile)%print([std_out], 1)
197 : :
198 [ + + ]: 48 : if (ifile == 1) call metric(gmet,gprimd,-1,rmet,Hscr_file(ifile)%Hdr%rprimd,ucvol)
199 : : end do !ifile
200 : :
201 [ + + ]: 16 : if (nfiles > 1) then
202 : : ! Put the correct ending on the output file
203 [ + + + - : 12 : if (is_scr) fname_out=TRIM(fname_out)//'_SCR'
+ - ]
204 [ + + + - : 12 : if (is_sus) fname_out=TRIM(fname_out)//'_SUS'
+ - ]
205 : : end if
206 : :
207 : : ! Produce output file in netcdf format we are merging netcdf files.
208 [ + - ]: 16 : if (iomode == IO_MODE_ETSF .and. .not. endswith(fname_out, ".nc")) fname_out = nctk_ncify(fname_out)
209 : :
210 : : !============================
211 : : !=== Merge multiple files ===
212 : : !============================
213 [ + + ]: 16 : if (nfiles > 1) then
214 : :
215 : : ! Check what kind of merging is to be performed
216 : 12 : write(std_out,'(2(a))') ch10,' Do you want to merge q-points (= 1) ?'
217 : 12 : write(std_out,'(a)') ' or do you want to merge frequencies (= 2) ?'
218 : 12 : read(std_in,*)choice
219 : :
220 : 6 : select case(choice)
221 : : case (1)
222 : 6 : write(std_out,'(3a)') ch10,' 1 => merging q-points',ch10
223 : 6 : call ioscr_qmerge(nfiles, filenames, hscr_file, fname_out, hscr_merge)
224 : :
225 : : case (2)
226 : : ! Merge frequencies
227 : 6 : write(std_out,'(3a)') ch10,' 2 => merging frequency grids',ch10
228 : : !ABI_WARNING("Advanced user option, consistency in fform etc. will not be checked.")
229 : :
230 : 6 : write(std_out,'(2a)') ch10,' Enter freqremax [eV] for the merged file (Enter 0 to use all freq. found):'
231 : 6 : read(std_in,*)freqremax
232 [ + - ]: 6 : freqremax = freqremax/Ha_eV; if (freqremax<tol16) freqremax = HUGE(freqremax)
233 : :
234 : 6 : call ioscr_wmerge(nfiles, filenames, hscr_file, freqremax, fname_out, hscr_merge)
235 : :
236 : : case default
237 [ + + - ]: 12 : ABI_ERROR(sjoin("Invalid choice!", itoa(choice)))
238 : : end select
239 : :
240 : : end if ! nfiles>1
241 : :
242 : : ! Now check if the list of q-points is complete
243 : : ! Here we assume that the k-mesh reported in the header is the same as that used during the sigma calculation.
244 : 16 : write(msg,'(3a)') ch10,' Checking if the list of q-points is complete. ',ch10
245 : 16 : call wrtout(std_out, msg)
246 : :
247 : : !call hscr_check_qpoints(hscr0)
248 : :
249 : 16 : Hscr0 => Hscr_file(1)
250 : 16 : fname =filenames(1)
251 [ + + ]: 16 : if (nfiles>1) then
252 : 12 : Hscr0 => Hscr_merge
253 : 12 : fname = fname_out
254 : : end if
255 : :
256 [ - + - + : 16 : cryst = HScr0%Hdr%get_crystal(remove_inv=.FALSE.)
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + ]
257 : :
258 : 16 : kptopt = 1
259 : 16 : call Kmesh%init(Cryst,HScr0%Hdr%nkpt,Hscr0%Hdr%kptns,kptopt)
260 [ + + ]: 32 : call Kmesh%print([std_out], header="K-mesh for the wavefunctions", prtvol=prtvol)
261 : :
262 : 16 : call qmesh%find_qmesh(Cryst, Kmesh)
263 [ + + ]: 32 : call qmesh%print([std_out], header="Q-mesh for the screening function", prtvol=prtvol)
264 : :
265 [ + - - + : 16 : ABI_MALLOC(foundq,(Qmesh%nibz))
- + - + -
+ - + -
+ ]
266 [ + + ]: 120 : foundq(:)=0
267 [ + + ]: 120 : do iqibz=1,Qmesh%nibz
268 [ + + ]: 808 : do iqf=1,Hscr0%nqibz
269 [ + + ]: 2752 : qdiff(:)=Qmesh%ibz(:,iqibz)-Hscr0%qibz(:,iqf)
270 [ + + ]: 792 : if (normv(qdiff,gmet,'G')<GW_TOLQ) foundq(iqibz)=foundq(iqibz)+1
271 : : end do
272 : : end do
273 : :
274 [ + + - + : 120 : if (ANY(foundq==0)) then
- + ]
275 : 0 : write(msg,'(6a)')ch10,&
276 [ # # ]: 0 : ' File ',TRIM(fname),' is not complete ',ch10,' The following q-points are missing:'
277 : 0 : call wrtout(std_out, msg)
278 : 0 : ii=0
279 [ # # ]: 0 : do iqibz=1,Qmesh%nibz
280 [ # # ]: 0 : if (foundq(iqibz)==0) then
281 : 0 : ii=ii+1
282 : 0 : write(msg,'(i3,a,3f12.6)')ii,') ',Qmesh%ibz(:,iqibz)
283 : 0 : call wrtout(std_out, msg)
284 : : end if
285 : : end do
286 : : end if
287 : :
288 [ + + - + : 120 : if (ANY(foundq>1)) then
- + ]
289 : 0 : write(msg,'(6a)')ch10,&
290 [ # # ]: 0 : ' File ',TRIM(fname),' is overcomplete ',ch10,' The following q-points are present more than once:'
291 : 0 : call wrtout(std_out, msg)
292 : 0 : ii=0
293 [ # # ]: 0 : do iqibz=1,Qmesh%nibz
294 [ # # ]: 0 : if (foundq(iqibz)>1) then
295 : 0 : ii=ii+1
296 : 0 : write(msg,'(i3,a,3f12.6)')ii,') ',Qmesh%ibz(:,iqibz)
297 : 0 : call wrtout(std_out, msg)
298 : : end if
299 : : end do
300 : : end if
301 : :
302 [ + + - + : 120 : if (ALL(foundq==1)) then
+ - ]
303 [ + - ]: 16 : write(msg,'(5a)')ch10,'.File ',TRIM(fname),' contains a complete list of q-points ',ch10
304 : 16 : call wrtout(std_out, msg)
305 : : end if
306 : :
307 : : !=====================
308 : : !=== Recovery mode ===
309 : : !=====================
310 [ + + ]: 16 : if (nfiles==1) then
311 : :
312 : 4 : write(std_out,'(2(a))') ch10,' Do you want to recover a subset of q-points (= 1) ?'
313 : 4 : write(std_out,'(a)') ' or extract the contents of the file (= 2) ?'
314 : 4 : write(std_out,'(a)') ' or create dielectric function (SCR file)'
315 : 4 : write(std_out,'(a)') ' and/or extract plasmon-pole parameters (= 3) ?'
316 : 4 : write(std_out,'(a)') ' or remove real frequencies (= 4) ?'
317 : 4 : write(std_out,'(a)') ' or remove imaginary frequencies (= 5) ?'
318 : 4 : write(std_out,'(a)') ' or calculate a model screening (= 6) ?'
319 : : !write(std_out,'(a)') ' or interpolate the screening in k-space (= 8) ?'
320 : 4 : read(std_in,*)choice
321 : :
322 : 2 : select case(choice)
323 : : case (1)
324 : : ! Recover subset of q-points --------------------------------------------------
325 : 2 : write(std_out,'(a)') ' 1 => Recovering subset of q-points'
326 : 2 : call prompt(' Enter the number of q-points to be extracted: ',nq_selected)
327 : 2 : call prompt(' Enter the name of the final output file: ',fname_out)
328 : :
329 [ + - ]: 2 : if (endswith(filenames(1), ".nc") .and. .not. endswith(fname_out, ".nc")) then
330 : 2 : fname_out = nctk_ncify(fname_out)
331 : 2 : call wrtout(std_out,"- Added .nc extension to output file as input data is in netcdf format.")
332 : : end if
333 : :
334 : 2 : call ioscr_qrecover(filenames(1), nq_selected, fname_out)
335 : :
336 : : case (2)
337 : : ! Analyse file ----------------------------------------------------------------
338 [ # # ]: 0 : ABI_CHECK(iomode==IO_MODE_FORTRAN, "netcdf output not coded")
339 : 0 : write(std_out,'(a)') ' 2 => Extraction of file contents'
340 : :
341 : : ! Initialize the G-sphere.
342 : 0 : call Gsphere%init(Cryst,Hscr0%npwe,gvec=Hscr0%gvec)
343 : :
344 [ # # # # : 0 : ABI_MALLOC_OR_DIE(tmp_epsm1, (Hscr0%npwe,Hscr0%npwe,Hscr0%nomega,1), ierr)
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
345 : :
346 : : ! Give option to output epsilon instead of chi0
347 : 0 : calc_epsilon = .FALSE.
348 [ # # ]: 0 : if (is_sus) then
349 : 0 : write(std_out,'(2a)') ch10,' You have provided a chi_0 file for analysis. Would you like to output'
350 : 0 : write(std_out,'(2a)',advance='no') ' the dielectric function epsilon_GG'' ', '= delta_GG'' - v_G*chi0_GG''[Y/N] ? '
351 : 0 : read(std_in,*)ans
352 : :
353 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
354 : : ! Initialise Coulomb terms
355 [ # # ]: 0 : if (epsm1%Hscr%nqlwl==0) then
356 : 0 : nqlwl=1
357 [ # # # # : 0 : ABI_MALLOC(qlwl,(3,nqlwl))
# # # # #
# # # #
# ]
358 [ # # ]: 0 : qlwl(:,1)= GW_Q0_DEFAULT
359 : : else
360 : 0 : nqlwl=epsm1%Hscr%nqlwl
361 [ # # # # : 0 : ABI_MALLOC(qlwl,(3,nqlwl))
# # # # #
# # # #
# ]
362 [ # # # # ]: 0 : qlwl(:,:)=epsm1%Hscr%qlwl(:,1:nqlwl)
363 : : end if
364 : :
365 : 0 : Dtset%gw_icutcoul=3; Dtset%gw_rcut=zero
366 [ # # ]: 0 : Dtset%vcutgeo=(/zero,zero,zero/);
367 [ # # ]: 0 : Dtset%boxcenter=(/zero,zero,zero/)
368 : :
369 : 0 : write(std_out,'(2a)',advance='no') ch10,' Was a Coulomb cutoff technique used [Y/N] ? '
370 : 0 : read(std_in,*)ans
371 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
372 : 0 : write(std_out,'(2a)',advance='no') ' Enter gw_icutcoul: '
373 : 0 : read(std_in,*)Dtset%gw_icutcoul
374 : 0 : write(std_out,'(2a)',advance='no') ' Enter vcutgeo: '
375 : 0 : read(std_in,*)Dtset%vcutgeo
376 : 0 : write(std_out,'(2a)',advance='no') ' Enter boxcenter: '
377 : 0 : read(std_in,*)Dtset%boxcenter
378 : : end if
379 : 0 : dtset%ecutsigx = -one
380 : :
381 : : call Vcp%init(Gsphere,Cryst,Qmesh,Kmesh,Dtset%gw_rcut,Dtset%gw_icutcoul,&
382 : 0 : Dtset%vcutgeo,Dtset%ecutsigx,Hscr0%npwe,nqlwl,qlwl,comm)
383 [ # # ]: 0 : ABI_FREE(qlwl)
384 : :
385 : 0 : calc_epsilon = .TRUE.
386 : : end if
387 : : end if
388 : :
389 : 0 : ig1 = 0; ig2 = 0
390 : 0 : write(std_out,'(2(a),I0,a)',advance='NO') ch10,' Enter the starting index for G (1 - ',Hscr0%npwe,' ): '
391 : 0 : read(std_in,*)ig1_start
392 [ # # ]: 0 : if (ig1_start<1.OR.ig1_start>Hscr0%npwe) then
393 : 0 : ABI_ERROR(' Starting index out of bounds')
394 : : end if
395 : 0 : write(std_out,'(a,I0,a,I0,a)',advance='NO') ' Enter the ending index for G ( ',ig1_start,' - ',Hscr0%npwe,' ): '
396 : 0 : read(std_in,*)ig1_end
397 [ # # ]: 0 : if (ig1_end<ig1_start.OR.ig1_end>Hscr0%npwe) then
398 : 0 : ABI_ERROR(' Ending index out of bounds')
399 : : end if
400 : 0 : write(std_out,'(a,I0,a)',advance='NO') ' Enter the starting index for G'' (1 - ',Hscr0%npwe,' ): '
401 : 0 : read(std_in,*)ig2_start
402 [ # # ]: 0 : if (ig2_start<1.OR.ig2_start>Hscr0%npwe) then
403 : 0 : ABI_ERROR(' Starting index out of bounds')
404 : : end if
405 : 0 : write(std_out,'(a,I0,a,I0,a)',advance='NO') ' Enter the ending index for G'' ( ',ig2_start,' - ',Hscr0%npwe,' ): '
406 : 0 : read(std_in,*)ig2_end
407 [ # # ]: 0 : if (ig2_end<ig2_start.OR.ig2_end>Hscr0%npwe) then
408 : 0 : ABI_ERROR(' Ending index out of bounds')
409 : : end if
410 : :
411 : 0 : only_diag = .FALSE.
412 : 0 : write(std_out,'(a)',advance='no') ' Would you like to output only the diagonal [Y/N] ? '
413 : 0 : read(std_in,*)ans
414 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') only_diag = .TRUE.
415 : :
416 [ # # ]: 0 : do iqibz=1,Hscr0%nqibz
417 : : ! In the long wavelength limit we set q==0, because we still can use symmetries for the Body.
418 [ # # # # ]: 0 : qtmp(:)=Hscr0%qibz(:,iqibz); if (normv(qtmp,Cryst%gmet,'G')<GW_TOLQ0) qtmp(:)=zero
419 : :
420 : : ! FIXME
421 : 0 : varname = "none"
422 : 0 : call read_screening(varname,fname,Hscr0%npwe,1,Hscr0%nomega,tmp_epsm1,iomode,comm,iqiA=iqibz)
423 : :
424 [ # # ]: 0 : if (calc_epsilon) then ! Calculate epsilon
425 [ # # ]: 0 : do iomega=1,Hscr0%nomega
426 [ # # ]: 0 : if (iqibz==1) then
427 [ # # ]: 0 : if (nqlwl>1) then
428 : 0 : ABI_ERROR('nqlwl>1 not coded yet!')
429 : : end if
430 : 0 : vc_sqrt => Vcp%vcqlwl_sqrt(:,iqibz) ! Use Coulomb term for q-->0
431 : : else
432 : 0 : vc_sqrt => Vcp%vc_sqrt(:,iqibz)
433 : : end if
434 [ # # ]: 0 : do ig2=ig2_start,ig2_end
435 [ # # ]: 0 : do ig1=ig1_start,ig1_end
436 : 0 : tmp_epsm1(ig1,ig2,iomega,1) = -(vc_sqrt(ig1)**2)*tmp_epsm1(ig1,ig2,iomega,1)
437 : : end do ! ig1
438 : 0 : tmp_epsm1(ig2,ig2,iomega,1) = one + tmp_epsm1(ig2,ig2,iomega,1)
439 : : end do ! ig2
440 : : end do ! iomega
441 : : end if ! Do we calculate epsilon
442 : :
443 : : ! Find out the total number of frequencies along real/imaginary axes
444 : : ! and possibly in the z-plane
445 : 0 : nfreqre=0; nfreqim=0; nfreqc=0;
446 [ # # ]: 0 : do iomega=1,Hscr0%nomega
447 [ # # ]: 0 : if (ABS(REAL(Hscr0%omega(iomega)))<tol8.AND. ABS(AIMAG(Hscr0%omega(iomega)))<tol8) nfreqre = nfreqre + 1
448 [ # # ]: 0 : if (ABS(REAL(Hscr0%omega(iomega)))>tol8.AND. ABS(AIMAG(Hscr0%omega(iomega)))<tol8) nfreqre = nfreqre + 1
449 [ # # ]: 0 : if (ABS(REAL(Hscr0%omega(iomega)))<tol8.AND. ABS(AIMAG(Hscr0%omega(iomega)))>tol8) nfreqim = nfreqim + 1
450 : : end do
451 [ # # ]: 0 : if (Hscr0%nomega-nfreqre-nfreqim/=0) then
452 : 0 : write(std_out,'(/,a)') ' WARNING: There are frequencies in the full complex plane.'
453 : 0 : write(std_out,'(a)') ' The _SCR or _SUS file might not be suitable'
454 : 0 : write(std_out,'(a,/)') ' for self-energy calculations.'
455 : 0 : nfreqc = Hscr0%nomega-nfreqre-nfreqim
456 : : end if
457 : 0 : write(std_out,'(2a,I0,a)') ch10,' Found ',Hscr0%nomega,' frequencies.'
458 : 0 : write(std_out,'(2(a,I0),2a)') ' ',nfreqre,' real, and ',nfreqim,' imaginary.',ch10
459 [ # # ]: 0 : if (nfreqc>0) then
460 : 0 : write(std_out,'(a,I0)') ' There is a grid in the complex plane with ',nfreqc
461 : 0 : write(std_out,'(2a)') ' extra frequencies in the list.',ch10
462 : : end if
463 : :
464 : : ! Get Q index for name
465 : 0 : call int2char4(iqibz,tagq)
466 [ # # ]: 0 : ABI_CHECK((tagq(1:1)/='#'),'Bug: string length too short!')
467 : :
468 [ # # ]: 0 : if (nfreqre>0) then ! Output real frequency axis
469 [ # # ]: 0 : if (calc_epsilon) then
470 [ # # # # : 0 : fname_dump=TRIM(fname)//'_EPS_Q'//TRIM(tagq)
# # ]
471 : : else
472 [ # # # # : 0 : fname_dump=TRIM(fname)//'_Q'//TRIM(tagq)
# # ]
473 : : end if
474 : :
475 [ # # ]: 0 : if (open_file(fname_dump, msg, newunit=unt_dump, status='replace', form='formatted') /= 0) then
476 : 0 : ABI_ERROR(msg)
477 : : end if
478 : :
479 [ # # ]: 0 : do ig1=ig1_start,ig1_end
480 [ # # ]: 0 : do ig2=ig2_start,ig2_end
481 [ # # ]: 0 : if (only_diag.AND.ig1/=ig2) CYCLE
482 : : write(unt_dump,'(2(a,i8),/,a,3f12.6,/,a,3i6,a,3i6,/,a,/)')&
483 : 0 : '# ig1= ',ig1,' ig2= ',ig2,&
484 : 0 : '# q = ',Hscr0%qibz(:,iqibz),&
485 : 0 : '# G = ',Hscr0%gvec(:,ig1),' G''= ',Hscr0%gvec(:,ig2),&
486 : 0 : '# omega [eV] Re Im '
487 [ # # ]: 0 : do iomega=1,nfreqre
488 : 0 : write(unt_dump,'(f8.2,4x,2es16.8)') REAL(Hscr0%omega(iomega))*Ha_eV,&
489 : 0 : REAL(tmp_epsm1(ig1,ig2,iomega,1)),AIMAG(tmp_epsm1(ig1,ig2,iomega,1))
490 : : end do
491 : 0 : write(unt_dump,*)
492 : 0 : write(unt_dump,*)
493 : : end do !ig2
494 : : end do !ig1
495 : 0 : close(unt_dump)
496 : : end if ! Output real frequency axis
497 : :
498 [ # # ]: 0 : if (nfreqim>0) then ! output imaginary frequency axis
499 [ # # ]: 0 : if (calc_epsilon) then
500 [ # # # # : 0 : fname_dump=TRIM(fname)//'_EPS_Imfrq_Q'//TRIM(tagq)
# # ]
501 : : else
502 [ # # # # : 0 : fname_dump=TRIM(fname)//'_Imfrq_Q'//TRIM(tagq)
# # ]
503 : : end if
504 [ # # ]: 0 : if (open_file(fname_dump,msg,newunit=unt_dump,status='replace',form='formatted') /= 0) then
505 : 0 : ABI_ERROR(msg)
506 : : end if
507 [ # # ]: 0 : do ig1=ig1_start,ig1_end
508 [ # # ]: 0 : do ig2=ig2_start,ig2_end
509 [ # # ]: 0 : if (only_diag.AND.ig1/=ig2) CYCLE
510 : : write(unt_dump,'(a,i4,2(a,i8),/,a,3f12.6,/,a,3i6,a,3i6,/,a,/)')&
511 : 0 : '# index= ',idx,' ig1= ',ig1,' ig2= ',ig2,&
512 : 0 : '# q = ',Hscr0%qibz(:,iqibz),&
513 : 0 : '# G = ',Hscr0%gvec(:,ig1),' G''= ',Hscr0%gvec(:,ig2),&
514 : 0 : '# omega [eV] Re Im '
515 [ # # ]: 0 : do iomega=nfreqre+1,nfreqre+nfreqim
516 : 0 : write(unt_dump,'(f8.2,4x,2es16.8)') AIMAG(Hscr0%omega(iomega))*Ha_eV,tmp_epsm1(ig1,ig2,iomega,1)
517 : : end do
518 : 0 : write(unt_dump,*)
519 : 0 : write(unt_dump,*)
520 : : end do !ig2
521 : : end do !ig1
522 : 0 : close(unt_dump)
523 : : end if ! Check for imaginary frequencies
524 : :
525 : : ! Check for complex plane values
526 [ # # ]: 0 : if (nfreqc>0) then
527 [ # # ]: 0 : if (calc_epsilon) then
528 [ # # # # : 0 : fname_dump=TRIM(fname)//'_EPS_ZPLANE_Q'//TRIM(tagq)
# # ]
529 : : else
530 [ # # # # : 0 : fname_dump=TRIM(fname)//'_ZPLANE_Q'//TRIM(tagq)
# # ]
531 : : end if
532 : :
533 [ # # ]: 0 : if (open_file(fname_dump,msg,newunit=unt_dump,status='replace',form='formatted') /= 0) then
534 : 0 : ABI_ERROR(msg)
535 : : end if
536 : :
537 [ # # ]: 0 : do ig1=ig1_start,ig1_end
538 [ # # ]: 0 : do ig2=ig2_start,ig2_end
539 [ # # ]: 0 : if (only_diag.AND.ig1/=ig2) CYCLE
540 : : write(unt_dump,'(a,i4,2(a,i8),/,a,3f12.6,/,a,3i6,a,3i6,/,a,/)')&
541 : 0 : '# index= ',idx,' ig1= ',ig1,' ig2= ',ig2,&
542 : 0 : '# q = ',Hscr0%qibz(:,iqibz),&
543 : 0 : '# G = ',Hscr0%gvec(:,ig1),' G''= ',Hscr0%gvec(:,ig2),&
544 : 0 : '# omega [eV] Re Im '
545 [ # # ]: 0 : do iomega=1,nfreqre
546 : 0 : write(unt_dump,'(2(f8.2),4x,2es16.8)') REAL(Hscr0%omega(iomega))*Ha_eV,&
547 : 0 : AIMAG(Hscr0%omega(iomega))*Ha_eV,tmp_epsm1(ig1,ig2,iomega,1)
548 : : end do
549 : 0 : write(unt_dump,*)
550 [ # # ]: 0 : do ios=1,nfreqim
551 [ # # ]: 0 : do iomega=1,nfreqre
552 [ # # ]: 0 : if (iomega==1) then
553 : 0 : io = nfreqre + ios
554 : : else
555 : 0 : io = nfreqre + nfreqim + (ios-1)*(nfreqre-1) + (iomega-1)
556 : : end if
557 : 0 : write(unt_dump,'(2(f8.2),4x,2es16.8)') REAL(Hscr0%omega(io))*Ha_eV,&
558 : 0 : AIMAG(Hscr0%omega(io))*Ha_eV,tmp_epsm1(ig1,ig2,io,1)
559 : : end do
560 : 0 : write(unt_dump,*)
561 : : end do
562 : 0 : write(unt_dump,*)
563 : 0 : write(unt_dump,*)
564 : : end do !ig2
565 : : end do !ig1
566 : 0 : close(unt_dump)
567 : : end if ! Check for complex plane freqs
568 : :
569 : : end do !iqibz
570 : :
571 [ # # ]: 0 : ABI_FREE(tmp_epsm1)
572 : 0 : call Gsphere%free()
573 : :
574 : : case (3)
575 : : ! Extract dielectric function and plasmon-pole stuff --------------------------
576 [ # # ]: 0 : ABI_CHECK(iomode==IO_MODE_FORTRAN, "netcdf output not coded")
577 : 0 : write(std_out,'(a)') ' 3 => Calculation of dielectric function and plasmon-pole model'
578 : :
579 : 0 : npwe_asked=Hscr0%npwe; mqmem=Hscr0%nqibz
580 : 0 : call epsm1%from_file(fname, mqmem, npwe_asked, comm)
581 : :
582 : : ! Initialize the G-sphere ===
583 : 0 : call Gsphere%init(Cryst,Hscr0%npwe,gvec=Hscr0%gvec)
584 : :
585 : 0 : boxcutmin=two; igmax=Gsphere%shlim(Gsphere%nsh)
586 : 0 : ecut=epsm1%Hscr%Hdr%ecutdg
587 : :
588 : : call getng(boxcutmin,1,ecut,Gsphere%gmet,k0,MPI_enreg%me_fft,&
589 : 0 : mgfft,nfft,ngfft,MPI_enreg%nproc_fft,Cryst%nsym,paral_kgb0,Cryst%symrel,Cryst%tnons)
590 : :
591 : : ! I am using standard valued, it would be better to call indefo
592 : : ! ngfft(1:3)=epsm1%Hscr%Hdr%ngfft(1:3)
593 : 0 : ngfft(7)=112
594 : 0 : ngfft(8)=get_cache_kb()
595 [ # # ]: 0 : nfft = PRODUCT(ngfft(1:3))
596 : :
597 : 0 : Dtset%gw_icutcoul=3; Dtset%gw_rcut=zero
598 [ # # # # ]: 0 : Dtset%vcutgeo=(/zero,zero,zero/); Dtset%boxcenter=(/zero,zero,zero/)
599 : 0 : Dtset%ecutsigx = -1
600 : :
601 [ # # ]: 0 : if (epsm1%Hscr%nqlwl==0) then
602 : 0 : nqlwl=1
603 [ # # # # : 0 : ABI_MALLOC(qlwl,(3,nqlwl))
# # # # #
# # # #
# ]
604 [ # # ]: 0 : qlwl(:,1)= GW_Q0_DEFAULT
605 : : else
606 : 0 : nqlwl=epsm1%Hscr%nqlwl
607 [ # # # # : 0 : ABI_MALLOC(qlwl,(3,nqlwl))
# # # # #
# # # #
# ]
608 [ # # # # ]: 0 : qlwl(:,:)=epsm1%Hscr%qlwl(:,1:nqlwl)
609 : : end if
610 : :
611 : : call Vcp%init(Gsphere,Cryst,Qmesh,Kmesh,Dtset%gw_rcut,Dtset%gw_icutcoul,Dtset%vcutgeo,Dtset%ecutsigx,&
612 : 0 : Hscr0%npwe,nqlwl,qlwl,comm)
613 [ # # ]: 0 : ABI_FREE(qlwl)
614 : :
615 : : ! Get the density from an external file ===
616 : : ! If meshes are not the same, do an FFT interpolation to have rhor on ngfft.
617 : 0 : call prompt(' Enter name for external DEN (or PAWDEN) file: ', fname_rho)
618 : :
619 [ # # # # : 0 : ABI_MALLOC(rhor,(nfft,Hscr0%Hdr%nspden))
# # # # #
# # # # #
# # # # ]
620 [ # # # # : 0 : ABI_MALLOC(pawrhoij,(Hscr0%Hdr%natom*Hscr0%Hdr%usepaw))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
621 : :
622 : 0 : call read_rhor(fname_rho, cplex1, nfft, Hscr0%Hdr%nspden, ngfft, 1, MPI_enreg, rhor, hdr_rhor, pawrhoij, comm)
623 : :
624 : 0 : call hdr_rhor%free()
625 : 0 : call pawrhoij_free(pawrhoij)
626 [ # # # # : 0 : ABI_FREE(pawrhoij)
# # # # #
# # # # #
# # # # ]
627 : :
628 [ # # # # : 0 : ABI_MALLOC(rhog,(2,nfft))
# # # # #
# # # #
# ]
629 : 0 : call fourdp(1,rhog,rhor(:,1),-1,MPI_enreg,nfft,1,ngfft,0)
630 : :
631 [ # # # # : 0 : ABI_MALLOC(nhat,(nfft,Hscr0%Hdr%nspden*Hscr0%Hdr%usepaw))
# # # # #
# # # # #
# # # # ]
632 : 0 : compch_sph=greatest_real; compch_fft=greatest_real
633 : 0 : usexcnhat=0; usefinegrid=0
634 : :
635 : 0 : nelectron_exp = Hscr0%Hdr%nelect
636 : :
637 : : call test_charge(nfft,nelectron_exp,Hscr0%Hdr%nspden,rhor,Cryst%ucvol,&
638 : 0 : Hscr0%Hdr%usepaw,usexcnhat,usefinegrid,compch_sph,compch_fft,drude_plsmf)
639 : 0 : GN_drude_plsmf = drude_plsmf
640 : :
641 : : ! Read and in case make Epsilon^{-1} according the the options specified
642 : 0 : id_required=4; ikxc=0; approx_type=0; option_test=0; dim_kxcg=0
643 [ # # # # : 0 : ABI_MALLOC(kxcg,(nfft,dim_kxcg))
# # # # #
# # # # #
# # # # ]
644 : :
645 : 0 : call prompt(' Enter prefix for output files: ',prefix)
646 [ # # # # ]: 0 : fname_dump=TRIM(prefix)//'_SCR'
647 : :
648 : 0 : orig_npwe = epsm1%npwe
649 : 0 : write(std_out,'(2a,I0)') ch10,' Number of plane waves is: ',epsm1%npwe
650 : 0 : write(std_out,'(a)',advance='no') ' Would you like to change it [Y/N] ?'
651 : 0 : read(std_in,*) ans
652 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
653 : 0 : write(std_out,'(a)',advance='no') ' Enter new no. of plane waves (0 means use old value): '
654 : 0 : read(std_in,*) ii
655 [ # # ]: 0 : if (ii>0.or.ii<=epsm1%npwe) epsm1%npwe = ii
656 [ # # ]: 0 : if (ii<0.or.ii>epsm1%npwe) then
657 : 0 : ABI_ERROR(' Wrong value for no. of plane waves!')
658 : : end if
659 : : end if
660 : :
661 [ # # ]: 0 : if (is_scr) epsm1%mqmem=1
662 [ # # ]: 0 : if (is_sus) epsm1%mqmem=0
663 : : call epsm1%mkdump(Vcp,epsm1%npwe,Gsphere%gvec,dim_kxcg,kxcg,id_required,approx_type,ikxc,option_test,&
664 : 0 : fname_dump,iomode,nfft,ngfft,comm)
665 : 0 : epsm1%mqmem=1
666 [ # # ]: 0 : call epsm1%print([std_out], 0)
667 : :
668 : 0 : write(std_out,'(2a)',advance='no') ch10,' Would you like to calculate the eigenvalues of eps^{-1}_GG''(omega) [Y/N] ? '
669 : 0 : read(std_in,*) ans
670 : :
671 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
672 [ # # # # : 0 : ABI_MALLOC(epsm1_eigen,(epsm1%npwe,epsm1%nomega))
# # # # #
# # # # #
# # # # ]
673 : 0 : imax = 10
674 [ # # ]: 0 : if (epsm1%npwe < imax) imax = epsm1%npwe
675 [ # # ]: 0 : do iqibz=1,epsm1%nqibz
676 : 0 : call int2char4(iqibz,tagq)
677 [ # # ]: 0 : ABI_CHECK((tagq(1:1)/='#'),'Bug: string length too short!')
678 [ # # # # : 0 : fname_eigen=TRIM(prefix)//'_EM1_EIG_Q'//TRIM(tagq)
# # ]
679 [ # # ]: 0 : if (open_file(fname_eigen,msg,newunit=unt_dump,status='replace',form='formatted') /= 0) then
680 : 0 : ABI_ERROR(msg)
681 : : end if
682 : 0 : call epsm1%decompose_epsm1(iqibz,epsm1_eigen)
683 : 0 : write(unt_dump,'(a)') '# First (max 10) eigenvalues of eps^{-1}(omega)'
684 : 0 : write(unt_dump,'(a,3f12.6)')'# q = ',Hscr0%qibz(:,iqibz)
685 : 0 : write(unt_dump,'(a)') '# REAL omega [eV] REAL(eigen(esp^-1(1,w))) AIMAG(eigen(esp^-1(1,w)) ...'
686 [ # # ]: 0 : do iomega=1,epsm1%nomega_r
687 : 0 : write(unt_dump,'(21(es16.8))')REAL(epsm1%omega(iomega))*Ha_eV,&
688 [ # # # # : 0 : (REAL(epsm1_eigen(ii,iomega)),ii=1,imax),(AIMAG(epsm1_eigen(ii,iomega)),ii=1,imax)
# # # # ]
689 : : end do
690 : 0 : close(unt_dump)
691 : : end do
692 [ # # ]: 0 : ABI_FREE(epsm1_eigen)
693 [ # # ]: 0 : ABI_FREE(kxcg)
694 : : end if ! Calculate eigenvalues
695 : :
696 : : ! Analyze the PPmodel.
697 : 0 : write(std_out,'(2a)') ch10,' Would you like to analyse plasmon-pole models [Y/N] ? '
698 : 0 : read(std_in,*)ans
699 : :
700 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
701 : 0 : write(std_out,'(2a,f6.2,a)') ch10,' Plasma frequency for GN PPM is: ',GN_drude_plsmf*Ha_eV, ' eV'
702 : 0 : write(std_out,'(a)',advance='no') ' Would you like to change it [Y/N] ?'
703 : 0 : read(std_in,*) ans
704 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
705 : 0 : write(std_out,'(2a)',advance='no') ch10,' Enter plasma frequency [eV]: '
706 : 0 : read(std_in,*) GN_drude_plsmf
707 : 0 : GN_drude_plsmf = GN_drude_plsmf/Ha_eV
708 : : end if
709 : :
710 : 0 : write(std_out,'(2a)') ch10,' Would you like to calculate the plasmon-pole model'
711 : 0 : write(std_out,'(a)',advance='no') ' eigenvalues of eps^{-1}_GG''(omega) [Y/N] ? '
712 : 0 : read(std_in,*) ans
713 : :
714 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
715 [ # # # # : 0 : ABI_MALLOC(ppm_eigen,(PPm%npwc,epsm1%nomega))
# # # # #
# # # # #
# # # # ]
716 [ # # ]: 0 : imax = 10; if (epsm1%npwe < imax) imax = epsm1%npwe
717 [ # # ]: 0 : do iqibz=1,epsm1%nqibz
718 [ # # ]: 0 : do ppmodel=1,2
719 : :
720 : 0 : call int2char4(iqibz,tagq)
721 [ # # ]: 0 : ABI_CHECK((tagq(1:1)/='#'),'Bug: string length too short!')
722 [ # # # # : 0 : if (ppmodel==1) fname_dump=TRIM(prefix)//'_PPM_GN_EM1_EIG_Q'//TRIM(tagq)
# # # # ]
723 [ # # # # : 0 : if (ppmodel==2) fname_dump=TRIM(prefix)//'_PPM_HL_EM1_EIG_Q'//TRIM(tagq)
# # # # ]
724 [ # # # # : 0 : if (ppmodel==3) fname_dump=TRIM(prefix)//'_PPM_vdLH_EM1_EIG_Q'//TRIM(tagq)
# # # # ]
725 [ # # # # : 0 : if (ppmodel==4) fname_dump=TRIM(prefix)//'_PPM_EF_EM1_EIG_Q'//TRIM(tagq)
# # # # ]
726 : :
727 [ # # ]: 0 : if (open_file(fname_eigen,msg,newunit=unt_dump,status='new',form='formatted') /= 0) then
728 : 0 : ABI_ERROR(msg)
729 : : end if
730 : :
731 : 0 : call PPm%free()
732 [ # # ]: 0 : if (ppmodel==1) then
733 : 0 : call PPm%init(epsm1%mqmem,epsm1%nqibz,epsm1%npwe,ppmodel,GN_drude_plsmf,Dtset%gw_invalid_freq)
734 : : else
735 : 0 : call PPm%init(epsm1%mqmem,epsm1%nqibz,epsm1%npwe,ppmodel,drude_plsmf,Dtset%gw_invalid_freq)
736 : : end if
737 : :
738 : 0 : call PPm%setup(Cryst,Qmesh,epsm1%npwe,epsm1%nomega,epsm1%omega,epsm1%epsm1,nfft,Gsphere%gvec,ngfft,rhor(:,1),iqibz)
739 : :
740 : 0 : call PPm%get_eigenvalues(iqibz,epsm1%Hscr%zcut,epsm1%nomega,epsm1%omega,Vcp,ppm_eigen)
741 : :
742 : 0 : write(unt_dump,'(a)') '# First (max 10) eigenvalues of eps^{-1}(omega) from Plasmon-pole model'
743 : 0 : write(unt_dump,'(a,3f12.6)')'# q = ',Hscr0%qibz(:,iqibz)
744 : :
745 : 0 : select case(ppmodel)
746 : : case (1)
747 : 0 : write(unt_dump,'(a)') '# ppmodel = 1 : Godby - Needs'
748 : : case (2)
749 : 0 : write(unt_dump,'(a)') '# ppmodel = 2 : Hybertsen - Louie'
750 : : case (3)
751 : 0 : write(unt_dump,'(a)') '# ppmodel = 3 : von der Linden - Horsch'
752 : : case (4)
753 [ # # # # : 0 : write(unt_dump,'(a)') '# ppmodel = 4 : Engel - Farid'
# ]
754 : : end select
755 : :
756 : 0 : write(unt_dump,'(a)') '# REAL omega [eV] REAL(eigen(ppm_eps^-1(1,w))) AIMAG(eigen(ppm_eps^-1(1,w)) ...'
757 [ # # ]: 0 : do iomega=1,epsm1%nomega_r
758 : 0 : write(unt_dump,'(21(es16.8))')REAL(epsm1%omega(iomega))*Ha_eV,&
759 [ # # # # : 0 : (REAL(ppm_eigen(ii,iomega)),ii=1,imax),(AIMAG(ppm_eigen(ii,iomega)),ii=1,imax)
# # # # ]
760 : : end do
761 : 0 : close(unt_dump)
762 : :
763 : : end do !ppmodel
764 : : end do ! iqibz
765 [ # # ]: 0 : ABI_FREE(ppm_eigen)
766 : : end if ! Calculate PPM eigenvalues
767 : :
768 : : ! Optionally output eps^{-1}_GG''(w) for a given set of GG' and gridpoints
769 : 0 : write(std_out,'(2a)',advance='no') ch10,' Would you like to extract eps^{-1}_GG''(omega) for the PPM [Y/N] ?'
770 : 0 : read(std_in,*) ans
771 : :
772 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
773 : : ! Reconstruct e^{-1}_GG'(w) according to PPmodel for statistical analysis.
774 : 0 : write(std_out,'(a)') ' Enter the number of frequency points in the'
775 : 0 : write(std_out,'(a)') ' interval 0 - freqremax (0 means same as input file ): '
776 : 0 : read(std_in,*) nfreqre
777 : :
778 [ # # ]: 0 : if (nfreqre==0) then
779 : 0 : nfreqre = epsm1%nomega_r
780 : 0 : nfreqim = epsm1%nomega_i
781 : 0 : nfreq_tot = epsm1%nomega
782 : 0 : freqremax = REAL(epsm1%omega(epsm1%nomega_r))
783 [ # # # # : 0 : ABI_MALLOC(omega,(nfreq_tot))
# # # # #
# # # #
# ]
784 [ # # ]: 0 : omega(:) = epsm1%omega(:)
785 : 0 : same_freqs = .TRUE.
786 : : else
787 : 0 : write(std_out,'(a)') ' Enter the value of freqremax (in eV): '
788 : 0 : read(std_in,*) freqremax
789 : 0 : nfreqim = epsm1%nomega_i
790 : 0 : nfreq_tot = nfreqre+nfreqim
791 [ # # # # : 0 : ABI_MALLOC(omega,(nfreqre+epsm1%nomega_i))
# # # # #
# # # #
# ]
792 [ # # ]: 0 : do iomega=1,nfreqre
793 : 0 : omega(iomega) = CMPLX((freqremax/REAL((nfreqre-1)))*(iomega-1),zero)
794 : : end do
795 [ # # ]: 0 : omega(nfreqre+1:nfreq_tot) = epsm1%omega(epsm1%nomega_r+1:epsm1%nomega)
796 : 0 : same_freqs = .FALSE.
797 : : end if ! frequencies
798 : :
799 [ # # ]: 0 : do iqibz=1,epsm1%nqibz
800 [ # # # # ]: 0 : qtmp(:)=epsm1%qibz(:,iqibz); if (normv(qtmp,Cryst%gmet,'G')<GW_TOLQ0) qtmp(:)=zero
801 : 0 : call int2char4(iqibz,tagq)
802 [ # # ]: 0 : ABI_CHECK((tagq(1:1)/='#'),'Bug: string length too short!')
803 : :
804 : : ! At this time only the Godby-Needs and Hybertsen-Louie models
805 : : ! TODO: Check the results from the others
806 [ # # ]: 0 : do ppmodel=1,2
807 : :
808 : 0 : call PPm%free()
809 [ # # ]: 0 : if (ppmodel==1) then
810 : 0 : call PPm%init(epsm1%mqmem,epsm1%nqibz,epsm1%npwe,ppmodel,GN_drude_plsmf,Dtset%gw_invalid_freq)
811 : : else
812 : 0 : call PPm%init(epsm1%mqmem,epsm1%nqibz,epsm1%npwe,ppmodel,drude_plsmf,Dtset%gw_invalid_freq)
813 : : end if
814 : 0 : call PPm%setup(Cryst,Qmesh,epsm1%npwe,epsm1%nomega,epsm1%omega,epsm1%epsm1,nfft,Gsphere%gvec,ngfft,rhor(:,1),iqibz)
815 : :
816 : : ! Prepare file for data on real omega axis
817 [ # # # # : 0 : if (ppmodel==1) fname_dump=TRIM(prefix)//'_PPM_w_GN_Q'//TRIM(tagq)
# # # # ]
818 [ # # # # : 0 : if (ppmodel==2) fname_dump=TRIM(prefix)//'_PPM_w_HL_Q'//TRIM(tagq)
# # # # ]
819 [ # # # # : 0 : if (ppmodel==3) fname_dump=TRIM(prefix)//'_PPM_w_vdLH_Q'//TRIM(tagq)
# # # # ]
820 [ # # # # : 0 : if (ppmodel==4) fname_dump=TRIM(prefix)//'_PPM_w_EF_Q'//TRIM(tagq)
# # # # ]
821 : :
822 [ # # ]: 0 : if (open_file(fname_dump,msg,newunit=unt_dump,status='replace',form='formatted') /= 0) then
823 : 0 : ABI_ERROR(msg)
824 : : end if
825 : :
826 : : ! Prepare file for data on imaginary omega axis
827 [ # # # # : 0 : if (ppmodel==1) fname_dump2=TRIM(prefix)//'_PPM_iw_GN_Q'//TRIM(tagq)
# # # # ]
828 [ # # # # : 0 : if (ppmodel==2) fname_dump2=TRIM(prefix)//'_PPM_iw_HL_Q'//TRIM(tagq)
# # # # ]
829 [ # # # # : 0 : if (ppmodel==3) fname_dump2=TRIM(prefix)//'_PPM_iw_vdLH_Q'//TRIM(tagq)
# # # # ]
830 [ # # # # : 0 : if (ppmodel==4) fname_dump2=TRIM(prefix)//'_PPM_iw_EF_Q'//TRIM(tagq)
# # # # ]
831 : :
832 [ # # ]: 0 : if (open_file(fname_dump2,msg,newunit=unt_dump2,status='replace',form='formatted') /= 0) then
833 : 0 : ABI_ERROR(msg)
834 : : end if
835 : :
836 [ # # # # : 0 : ABI_MALLOC(em1_ppm,(nfreq_tot))
# # # # #
# # # #
# ]
837 : :
838 : 0 : ig1 = 0; ig2 = 0
839 : 0 : write(std_out,'(3a,I0,a,I0)') ch10,' Enter indices for G and G''.',&
840 : 0 : 'Entering 0 exits the loop. iqibz = ',iqibz,' ppmodel = ',ppmodel
841 : :
842 : 0 : do
843 : 0 : write(std_out,'(2(a),I0,a)',advance='NO') ch10,' Enter index for G (1 - ',epsm1%npwe,' ): '
844 : 0 : read(std_in,*)ig1
845 [ # # ]: 0 : if (ig1==0) EXIT
846 [ # # ]: 0 : if (ig1<0.OR.ig1>epsm1%npwe) ABI_ERROR(' index out of bounds')
847 : 0 : write(std_out,'(2(a),I0,a)',advance='NO') ch10,' Enter index for G'' (1 - ',epsm1%npwe,' ): '
848 : 0 : read(std_in,*)ig2
849 [ # # ]: 0 : if (ig2==0) EXIT
850 [ # # ]: 0 : if (ig2<0.OR.ig2>epsm1%npwe) ABI_ERROR(' index out of bounds')
851 : :
852 : : ! Generate the PPM representation of epsilon^-1
853 : 0 : call PPM%getem1_one_ggp(iqibz,epsm1%Hscr%zcut,nfreq_tot,omega,Vcp,em1_ppm,ig1,ig2)
854 : :
855 [ # # # # ]: 0 : mat = two_pi*Cryst%gmet
856 : 0 : write(unt_dump,'(a,I1)') '# epsilon^-1_GG''(omega) from ppmodel = ',ppmodel
857 : : write(unt_dump,'(2(a,i8),/,a,3f12.6,/,a,3i6,a,3i6,/,a,3F9.4,a,3F9.4,a,/a,f9.4,a,f9.4,a,/,a,/)')&
858 : 0 : '# ig1= ',ig1,' ig2= ',ig2,&
859 : 0 : '# q = ',epsm1%qibz(:,iqibz),&
860 : 0 : '# G = ',epsm1%gvec(:,ig1),' G''= ',epsm1%gvec(:,ig2),&
861 [ # # # # : 0 : '# G = (',MATMUL(mat,epsm1%gvec(:,ig1)),&
# # ]
862 [ # # # # : 0 : ') G''= (',MATMUL(mat,epsm1%gvec(:,ig2)),')',&
# # ]
863 : 0 : '# 1/2|G|^2 =',half*normv(epsm1%gvec(:,ig1),Cryst%gmet,'G')**2,&
864 : 0 : ' Ha 1/2|G''|^2 =',half*normv(epsm1%gvec(:,ig2),Cryst%gmet,'G')**2,' Ha',&
865 : 0 : '# omega [eV] Re Im '
866 : 0 : write(unt_dump2,'(a,I1)') '# epsilon^-1_GG''(iomega) from ppmodel = ',ppmodel
867 : : write(unt_dump2,'(2(a,i8),/,a,3f12.6,/,a,3i6,a,3i6,/,a,3F9.4,a,3F9.4,a,/a,f9.4,a,f9.4,a,/,a,/)')&
868 : 0 : '# ig1= ',ig1,' ig2= ',ig2,&
869 : 0 : '# q = ',epsm1%qibz(:,iqibz),&
870 : 0 : '# G = ',epsm1%gvec(:,ig1),' G''= ',epsm1%gvec(:,ig2),&
871 [ # # # # : 0 : '# G = (',MATMUL(mat,epsm1%gvec(:,ig1)),&
# # ]
872 [ # # # # : 0 : ') G''= (',MATMUL(mat,epsm1%gvec(:,ig2)),')',&
# # ]
873 : 0 : '# 1/2|G|^2 =',half*normv(epsm1%gvec(:,ig1),Cryst%gmet,'G')**2,&
874 : 0 : ' Ha 1/2|G''|^2 =',half*normv(epsm1%gvec(:,ig2),Cryst%gmet,'G')**2,' Ha',&
875 : 0 : '# iomega [eV] Re Im '
876 : :
877 [ # # ]: 0 : do iomega=1,nfreqre
878 [ # # ]: 0 : if (same_freqs) then
879 : 0 : write(unt_dump,'(f8.2,4x,4es16.8)') REAL(omega(iomega))*Ha_eV,em1_ppm(iomega),&
880 : 0 : epsm1%epsm1(ig1,ig2,iomega,iqibz)
881 : : else
882 : 0 : write(unt_dump,'(f8.2,4x,2es16.8)') REAL(omega(iomega))*Ha_eV,em1_ppm(iomega)
883 : : end if
884 : : end do
885 : : ! First output the iomega = 0 point
886 : 0 : write(unt_dump2,'(f8.2,4x,4es16.8)') AIMAG(omega(1))*Ha_eV,em1_ppm(1), epsm1%epsm1(ig1,ig2,1,iqibz)
887 : : ! Then the rest
888 [ # # ]: 0 : do iomega=nfreqre+1,nfreq_tot
889 : 0 : write(unt_dump2,'(f8.2,4x,4es16.8)') AIMAG(omega(iomega))*Ha_eV,em1_ppm(iomega),epsm1%epsm1(ig1,ig2,iomega,iqibz)
890 : : end do
891 : 0 : write(unt_dump,*)
892 : 0 : write(unt_dump,*)
893 : 0 : write(unt_dump2,*)
894 : 0 : write(unt_dump2,*)
895 : : end do ! Empty
896 [ # # ]: 0 : ABI_FREE(em1_ppm)
897 : 0 : close(unt_dump); close(unt_dump2)
898 : :
899 : : end do ! ppmodel
900 : : end do ! iqibz
901 [ # # ]: 0 : ABI_FREE(omega)
902 : : end if ! Output epsilon for PPM
903 : :
904 : : ! Optionally statistics for all PPMs
905 : 0 : write(std_out,'(2a)',advance='no') ch10,' Would you like to output statistics for all PPMs [Y/N] ?'
906 : 0 : read(std_in,*) ans
907 : :
908 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
909 : 0 : nfreqre = epsm1%nomega_r
910 : 0 : nfreq_tot = epsm1%nomega
911 : 0 : freqremax = REAL(epsm1%omega(epsm1%nomega_r))
912 [ # # # # : 0 : ABI_MALLOC(real_omega,(nfreqre))
# # # # #
# # # #
# ]
913 [ # # ]: 0 : real_omega(:) = REAL(epsm1%omega(1:nfreqre))
914 : :
915 [ # # ]: 0 : do iqibz=1,epsm1%nqibz
916 [ # # ]: 0 : do ppmodel=1,2
917 : :
918 [ # # ]: 0 : qtmp(:)=epsm1%qibz(:,iqibz)
919 [ # # ]: 0 : if (normv(qtmp,Cryst%gmet,'G')<GW_TOLQ0) qtmp(:)=zero
920 : :
921 : 0 : call PPm%free()
922 [ # # ]: 0 : if (ppmodel==1) then
923 : 0 : call PPm%init(epsm1%mqmem,epsm1%nqibz,epsm1%npwe,ppmodel,GN_drude_plsmf,Dtset%gw_invalid_freq)
924 : : else
925 : 0 : call PPm%init(epsm1%mqmem,epsm1%nqibz,epsm1%npwe,ppmodel,drude_plsmf,Dtset%gw_invalid_freq)
926 : : end if
927 : 0 : call PPm%setup(Cryst,Qmesh,epsm1%npwe,epsm1%nomega,epsm1%omega,epsm1%epsm1,nfft,Gsphere%gvec,ngfft,rhor(:,1),iqibz)
928 : :
929 : : ! Prepare ratios and density for the f-sum rule
930 [ # # # # : 0 : ABI_MALLOC_OR_DIE(qratio,(orig_npwe,orig_npwe), ierr)
# # # # #
# # # # #
# # # # #
# # # ]
931 [ # # # # : 0 : ABI_MALLOC_OR_DIE(rhoggp,(epsm1%npwe,epsm1%npwe), ierr)
# # # # #
# # # # #
# # # # #
# # # ]
932 : :
933 : 0 : call cqratio(orig_npwe,Gsphere%gvec,qtmp,Cryst%gmet,Cryst%gprimd,qratio)
934 : : ! Arrange n(G-G')->n(G,G')
935 : 0 : ierr=0
936 [ # # ]: 0 : do ig1=1,epsm1%npwe
937 [ # # ]: 0 : do ig2=1,epsm1%npwe
938 [ # # # # ]: 0 : gmgp_idx = g2ifft(Gsphere%gvec(:,ig1)-Gsphere%gvec(:,ig2),ngfft)
939 [ # # ]: 0 : if (gmgp_idx/=0) then
940 : 0 : rhoggp(ig1,ig2)=CMPLX(rhog(1,gmgp_idx),rhog(2,gmgp_idx))
941 : : else
942 : 0 : ierr=ierr+1
943 : 0 : rhoggp(ig1,ig2)=czero
944 : : end if
945 : : end do
946 : : end do
947 [ # # ]: 0 : if (ierr/=0) then
948 : 0 : write(std_out,'(a,i0,a)')' Found ',ierr,' G1-G2 vectors falling outside the FFT box. '
949 : : end if
950 : :
951 : : ! Prepare files
952 : 0 : call int2char4(iqibz,tagq)
953 [ # # ]: 0 : ABI_CHECK((tagq(1:1)/='#'),'Bug: string length too short!')
954 [ # # # # : 0 : if (ppmodel==1) fname_dump=TRIM(prefix)//'_norms_GN_Q'//TRIM(tagq)
# # # # ]
955 [ # # # # : 0 : if (ppmodel==2) fname_dump=TRIM(prefix)//'_norms_HL_Q'//TRIM(tagq)
# # # # ]
956 [ # # ]: 0 : if (open_file(fname_dump,msg, newunit=unt_dump, status='replace',form='formatted') /= 0) then
957 : 0 : ABI_ERROR(msg)
958 : : end if
959 : 0 : write(unt_dump,'(a)') '# Various norms integrated through spline interpolation'
960 : 0 : write(unt_dump,'(a)') '# over all frequencies in the input file,'
961 : 0 : write(unt_dump,'(a)') '# for all G and G'' vectors.'
962 : 0 : write(unt_dump,'(a,I0)') '# ppmodel: ',ppmodel
963 : 0 : write(unt_dump,'(a,I0)') '# Number of frequencies: ',nfreqre
964 : 0 : write(unt_dump,'(a,f12.6)') '# Maximum frequency : ',freqremax
965 : 0 : write(unt_dump,'(a)') '# Columns:'
966 : 0 : write(unt_dump,'(2a)') '# ig1 ig2 |eps-eps_PPM|/|eps|',&
967 : 0 : ' |eps-eps_PPM| |eps| |eps_PPM| G G'''
968 [ # # # # : 0 : if (ppmodel==1) fname_dump2=TRIM(prefix)//'_f_sumrule_GN_Q'//TRIM(tagq)
# # # # ]
969 [ # # # # : 0 : if (ppmodel==2) fname_dump2=TRIM(prefix)//'_f_sumrule_HL_Q'//TRIM(tagq)
# # # # ]
970 : :
971 [ # # ]: 0 : if (open_file(fname_dump2,msg,newunit=unt_dump2,status='replace',form='formatted') /= 0) then
972 : 0 : ABI_ERROR(msg)
973 : : end if
974 : :
975 : 0 : write(unt_dump2,'(a)') '# The fulfillment of the f-sum rule: I(epsilon) ='
976 : 0 : write(unt_dump2,'(a)') '# int_0^{inf}{omega*Im[epsilon_G,G''(omega)]}/C_qGG'''
977 : 0 : write(unt_dump2,'(a)') '# C_qGG'' = '
978 : 0 : write(unt_dump2,'(a)') '# -Pi/2*omega_p^2*(q+G)*(q+G'')/|q+G|^2*n(G-G'')/n(0)'
979 : 0 : write(unt_dump2,'(a)') '# for all G and G'' vectors.'
980 : 0 : write(unt_dump2,'(a,I0)') '# ppmodel: ',ppmodel
981 : 0 : write(unt_dump2,'(a,I0)') '# Number of frequencies: ',nfreqre
982 : 0 : write(unt_dump2,'(a,f12.6)') '# Maximum frequency : ',freqremax
983 : 0 : write(unt_dump2,'(a)') '# Columns:'
984 : : write(unt_dump2,'(3a)') &
985 : 0 : '# ig1 ig2 I(epsilon)',&
986 : 0 : ' I(eps_PPM) Re[n(G-G'')] Im[n(G-G'')] qratio I1*C_qGG''',&
987 : 0 : ' Re[Omegatwsq] Im[Omegatwsq] Re[omegatw] Im[omegatw] |G| 1/2|G|^2'
988 : :
989 [ # # # # : 0 : ABI_MALLOC(em1_ppm,(nfreq_tot))
# # # # #
# # # #
# ]
990 [ # # # # : 0 : ABI_MALLOC(ftab,(nfreqre))
# # # # #
# # # #
# ]
991 [ # # # # : 0 : ABI_MALLOC(ysp,(3,nfreqre))
# # # # #
# # # #
# ]
992 [ # # # # : 0 : ABI_MALLOC(work,(nfreqre))
# # # # #
# # # #
# ]
993 [ # # # # : 0 : ABI_MALLOC(eint,(nfreqre))
# # # # #
# # # #
# ]
994 : :
995 [ # # ]: 0 : do ig1=1,epsm1%npwe
996 : 0 : write(std_out,'(2(a,I0))') ' ig1= ',ig1, ' of ',epsm1%npwe
997 [ # # ]: 0 : do ig2=1,epsm1%npwe
998 : : !ig2 = ig1
999 : 0 : call PPm%getem1_one_ggp(iqibz,epsm1%Hscr%zcut,nfreq_tot,epsm1%omega,Vcp,em1_ppm,ig1,ig2)
1000 : :
1001 : : ! Calculate norms in real
1002 : 0 : eps_diff=0; eps_norm=0; eps_ppm_norm=0
1003 [ # # ]: 0 : ftab(1:nfreqre) = ABS(epsm1%epsm1(ig1,ig2,1:nfreqre,iqibz)-em1_ppm(1:nfreqre))
1004 : 0 : call cspint(ftab,real_omega,nfreqre,real_omega(1),real_omega(nfreqre),ysp,eint,work,eps_diff)
1005 [ # # ]: 0 : ftab(1:nfreqre) = ABS(epsm1%epsm1(ig1,ig2,1:nfreqre,iqibz))
1006 : 0 : call cspint(ftab,real_omega,nfreqre,real_omega(1),real_omega(nfreqre),ysp,eint,work,eps_norm)
1007 [ # # ]: 0 : ftab(1:nfreqre) = ABS(em1_ppm(1:nfreqre))
1008 : 0 : call cspint(ftab,real_omega,nfreqre,real_omega(1),real_omega(nfreqre),ysp,eint,work,eps_ppm_norm)
1009 : 0 : write(unt_dump,'(2i6,f12.4,3es14.4,6i4)') ig1,ig2,eps_diff/eps_norm,eps_diff,&
1010 : 0 : eps_norm,eps_ppm_norm,epsm1%gvec(:,ig1),epsm1%gvec(:,ig2)
1011 : :
1012 : : ! Evaluate the f-sum rule
1013 [ # # ]: 0 : if (ig1==ig2) then
1014 [ # # ]: 0 : ftab(1:nfreqre) = real_omega(1:nfreqre)*AIMAG(epsm1%epsm1(ig1,ig2,1:nfreqre,iqibz))
1015 : : else
1016 : : ! Dephase first - HERE epsm1 is changed!
1017 [ # # ]: 0 : call remove_phase(tmp_epsm1(ig1,ig2,:,1),Hscr_file(1)%nomega,phase)
1018 [ # # ]: 0 : ftab(1:nfreqre) = real_omega(1:nfreqre)*AIMAG(epsm1%epsm1(ig1,ig2,1:nfreqre,iqibz))
1019 : : end if
1020 : :
1021 : 0 : call cspint(ftab,real_omega,nfreqre,real_omega(1),real_omega(nfreqre),ysp,eint,work,eps_diff)
1022 : :
1023 [ # # ]: 0 : if (ig1==ig2) then
1024 : 0 : factor = -two*pi*pi*REAL(rhoggp(ig1,ig2))*qratio(ig1,ig2)
1025 : : else
1026 : 0 : rhoggp(ig1,ig2) = CMPLX(COS(phase),-SIN(phase))*rhoggp(ig1,ig2)
1027 : 0 : factor = -two*pi*pi*REAL(rhoggp(ig1,ig2))*qratio(ig1,ig2)
1028 : : end if
1029 : :
1030 [ # # ]: 0 : if (ABS(qratio(ig1,ig2))>zero) then
1031 : 0 : value1 = eps_diff/factor
1032 [ # # ]: 0 : if (ppmodel==1) then
1033 : : value2 = -pi*half*(REAL(PPm%bigomegatwsq(iqibz)%vals(ig1,ig2))&
1034 : : /(REAL(PPm%omegatw(iqibz)%vals(ig1,ig2))))&
1035 : 0 : /factor*(2*sqrt(pi*rhoggp(1,1)))
1036 : : else
1037 : : value2 = -pi*half*(SQRT(REAL(PPm%bigomegatwsq(iqibz)%vals(ig1,ig2))))&
1038 : 0 : /factor*(2*sqrt(pi*rhoggp(1,1)))
1039 : : end if
1040 : : else
1041 : 0 : value1 = zero
1042 : 0 : value2 = zero
1043 : : end if
1044 : :
1045 : 0 : write(unt_dump2,'(2i6,12es14.4)') ig1,ig2,value1,value2,&
1046 : 0 : REAL(rhoggp(ig1,ig2)),AIMAG(rhoggp(ig1,ig2)),qratio(ig1,ig2),&
1047 : 0 : eps_diff,REAL(PPm%bigomegatwsq(iqibz)%vals(ig1,ig2)),&
1048 : 0 : AIMAG(PPm%bigomegatwsq(iqibz)%vals(ig1,ig2)),&
1049 : 0 : REAL(PPm%omegatw(iqibz)%vals(ig1,ig2)),&
1050 : 0 : AIMAG(PPm%omegatw(iqibz)%vals(ig1,ig2)),&
1051 : 0 : normv(epsm1%gvec(:,ig1),Cryst%gmet,'G'),&
1052 : 0 : half*normv(epsm1%gvec(:,ig1),Cryst%gmet,'G')**2
1053 : :
1054 : : end do !ig2
1055 : : end do !ig1
1056 : :
1057 [ # # ]: 0 : ABI_FREE(em1_ppm)
1058 [ # # ]: 0 : ABI_FREE(ftab)
1059 [ # # ]: 0 : ABI_FREE(ysp)
1060 [ # # ]: 0 : ABI_FREE(work)
1061 [ # # ]: 0 : ABI_FREE(eint)
1062 [ # # ]: 0 : ABI_FREE(qratio)
1063 [ # # ]: 0 : ABI_FREE(rhoggp)
1064 : 0 : close(unt_dump); close(unt_dump2)
1065 : :
1066 : : end do ! ppmodel
1067 : : end do ! iqibz
1068 : :
1069 [ # # ]: 0 : ABI_FREE(real_omega)
1070 : : end if ! Output statistics
1071 : :
1072 : 0 : call PPm%free()
1073 : : end if ! If ppmodel>0
1074 : :
1075 [ # # ]: 0 : ABI_FREE(rhor)
1076 [ # # ]: 0 : ABI_FREE(rhog)
1077 [ # # ]: 0 : ABI_FREE(nhat)
1078 : :
1079 : 0 : call Vcp%free(); call epsm1%free(); call Gsphere%free()
1080 : :
1081 : : case (4)
1082 : : ! Remove real frequencies ----------------------------------------------------------
1083 : 2 : write(std_out,'(2(a))') ch10,' Do you want to remove every other real frequency (= 1) ?'
1084 : 2 : write(std_out,'(a)') ' or specify for each real frequency individually (= 2) ?'
1085 : 2 : write(std_out,'(a)') ' or remove ALL real frequencies (= 3) ?'
1086 : 2 : read(std_in,*)choice
1087 : :
1088 : : ! Calculate the total number of real freq
1089 : 2 : nfreqre = 0; nfreqim = 0
1090 [ + + ]: 54 : do ifrq=1,Hscr_file(1)%nomega
1091 : : ! If frequency is not imaginary, count.
1092 [ + + ]: 52 : if (AIMAG(Hscr_file(1)%omega(ifrq)) < tol8) nfreqre = nfreqre + 1
1093 [ + + ]: 54 : if (REAL(Hscr_file(1)%omega(ifrq)) < tol8 .and. AIMAG(Hscr_file(1)%omega(ifrq))>tol8) nfreqim = nfreqim + 1
1094 : : end do
1095 : :
1096 : 2 : nfreq_tot = nfreqre + nfreqim ! Here nfreq_tot becomes the *true* number of freq
1097 : 2 : write(std_out,'(2a,I0,a)') ch10,' Found ',nfreq_tot,' frequencies.'
1098 : 2 : write(std_out,'(2(a,I0),2a)') ' ',nfreqre,' real, and ',nfreqim,' imaginary.',ch10
1099 : :
1100 : : ! Array with the index of frequencies to be kept.
1101 [ + - - + : 2 : ABI_MALLOC(freq_indx,(nfreq_tot,1))
- + - + -
+ - + -
+ ]
1102 [ + + + + ]: 56 : freq_indx = 0
1103 : :
1104 : 2 : select case (choice)
1105 : : case (1)
1106 : : ! Remove every other frequency
1107 : 2 : write(std_out,'(2(a))') ch10,' Removing every other real frequency, i.e. every even one.'
1108 : 2 : write(std_out,'(a)') ' If the total number of frequencies is odd, the first and last one will be kept.'
1109 : 2 : write(std_out,'(a)') ' If the total number is even, the first one will still be in the final set.'
1110 : :
1111 : : ! Test for no real frequencies
1112 [ - + ]: 2 : ABI_CHECK(nfreqre /= 0, "No real frequencies in file!")
1113 : :
1114 : 2 : ii=nfreqre; nfreqre = 0
1115 [ + + ]: 44 : do ifrq=1,ii
1116 [ + + ]: 44 : if (.not. iseven(ifrq)) then
1117 : 22 : nfreqre = nfreqre + 1; freq_indx(nfreqre,1) = ifrq
1118 : : end if
1119 : : end do
1120 : 2 : write(std_out,'(2a,I0,a)') ch10,' ',nfreqre,' real frequencies will be kept.'
1121 : :
1122 : : case (2)
1123 : : ! Specify freq. individually
1124 : 0 : ii = nfreqre; nfreqre = 0
1125 [ # # ]: 0 : do ifrq=1,ii
1126 : 0 : write(std_out,'(a,f12.6,a)') ' Would you like to keep freq. at: ',REAL(Hscr_file(1)%omega(ifrq))*Ha_eV,' eV? [y/n]'
1127 : 0 : read(std_in,*) ans
1128 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
1129 : 0 : nfreqre = nfreqre + 1; freq_indx(nfreqre,1) = ifrq
1130 : : end if
1131 : : end do
1132 : 0 : write(std_out,'(2a,I0,a)') ch10,' ',nfreqre,' real frequencies will be kept.'
1133 : :
1134 : : case (3)
1135 : : ! Remove all real freq.
1136 : 0 : nfreqre = 0
1137 : :
1138 : : case default
1139 [ + - - - ]: 2 : ABI_ERROR(sjoin("Invalid choice!", itoa(choice)))
1140 : : end select
1141 : :
1142 : : ! Add imaginary frequencies if any
1143 [ + - ]: 2 : if (nfreqim > 0) then
1144 : 2 : nfreqim = 0
1145 [ + + ]: 54 : do ifrq=1,Hscr_file(1)%nomega
1146 [ + + ]: 54 : if (AIMAG(Hscr_file(1)%omega(ifrq)) > tol8) then
1147 : 10 : nfreqim = nfreqim + 1; freq_indx(nfreqre+nfreqim,1) = ifrq
1148 : : end if
1149 : : end do
1150 : : end if
1151 : :
1152 : 2 : nfreq_tot = nfreqre + nfreqim ! Here nfreq_tot becomes the *true* number of freq
1153 : 2 : write(std_out,'(3(a,i0),a)')' Finally, we have ',nfreq_tot,' frequencies. ',nfreqre,' real, and ',nfreqim,' imaginary.'
1154 : :
1155 : 2 : call prompt(' Enter the full name of the final output file: ', fname_out)
1156 : :
1157 [ + - ]: 2 : if (endswith(filenames(1), ".nc") .and. .not. endswith(fname_out, ".nc")) then
1158 : 2 : fname_out = nctk_ncify(fname_out)
1159 : 2 : call wrtout(std_out,"- Added .nc extension to output file as input data is in netcdf format.")
1160 : : end if
1161 : :
1162 : 2 : call ioscr_wremove(filenames(1), hscr_file(1), fname_out, nfreq_tot, freq_indx, hscr_merge)
1163 [ - + ]: 2 : ABI_FREE(freq_indx)
1164 : :
1165 : : case (5)
1166 : : ! Remove imaginary frequencies ------------------------------------------------
1167 : :
1168 : : ! Calculate the total number of freq
1169 : 0 : nfreqre = 0; nfreqim = 0
1170 [ # # ]: 0 : do ifrq=1,Hscr_file(1)%nomega
1171 : : ! If frequency is not imaginary, count.
1172 [ # # ]: 0 : if (AIMAG(Hscr_file(1)%omega(ifrq))<tol8) nfreqre = nfreqre + 1
1173 [ # # ]: 0 : if (REAL(Hscr_file(1)%omega(ifrq))<tol8.and.AIMAG(Hscr_file(1)%omega(ifrq))>tol8) nfreqim = nfreqim + 1
1174 : : end do ! ifrq
1175 : :
1176 : : ! Test for no real frequencies
1177 [ # # ]: 0 : if (nfreqim == 0) then
1178 : 0 : ABI_ERROR("No imaginary frequencies in file!")
1179 : : end if
1180 : :
1181 : 0 : nfreq_tot = nfreqre + nfreqim ! Here nfreq_tot becomes the *true* number of freq
1182 : 0 : write(std_out,'(2a,I0,a)') ch10,' Found ',nfreq_tot,' frequencies.'
1183 : 0 : write(std_out,'(2(a,I0),2a)') ' ',nfreqre,' real, and ',nfreqim,' imaginary.',ch10
1184 : :
1185 [ # # # # : 0 : ABI_MALLOC(freq_indx,(nfreq_tot,1))
# # # # #
# # # #
# ]
1186 [ # # # # ]: 0 : freq_indx = 0
1187 : :
1188 : : ! Specify freq. individually
1189 : 0 : ii=nfreq_tot; nfreqim = 0
1190 [ # # ]: 0 : do ifrq=nfreqre+1,ii
1191 : : write(std_out,'(a,f12.6,a)')&
1192 : 0 : ' Would you like to keep imaginary freq. at: ',AIMAG(Hscr_file(1)%omega(ifrq))*Ha_eV,' eV? [y/n]'
1193 : 0 : read(std_in,*) ans
1194 [ # # ]: 0 : if (ans=='Y'.or.ans=='y') then
1195 : 0 : nfreqim = nfreqim + 1; freq_indx(nfreqre+nfreqim,1) = ifrq
1196 : : end if
1197 : : end do ! ifrq
1198 : 0 : write(std_out,'(2a,I0,a)') ch10,' ',nfreqim,' imaginary frequencies will be kept.'
1199 : :
1200 : : ! Add real frequencies if any
1201 [ # # ]: 0 : if (nfreqre > 0) then
1202 : 0 : nfreqre = 0
1203 [ # # ]: 0 : do ifrq=1,Hscr_file(1)%nomega
1204 [ # # ]: 0 : if (AIMAG(Hscr_file(1)%omega(ifrq)) < tol8) then
1205 : 0 : nfreqre = nfreqre + 1; freq_indx(nfreqre,1) = ifrq
1206 : : end if
1207 : : end do
1208 : : end if
1209 : :
1210 : 0 : nfreq_tot = nfreqre + nfreqim ! Here nfreq_tot becomes the *true* number of freq
1211 : 0 : write(std_out,'(2a,I0,a)') ch10,' Finally, we have ',nfreq_tot,' frequencies.'
1212 : 0 : write(std_out,'(2(a,I0),2a)') ' ',nfreqre,' real, and ',nfreqim,' imaginary.',ch10
1213 : :
1214 : 0 : call prompt(' Enter the full name of the final output file: ',fname_out)
1215 : :
1216 [ # # ]: 0 : if (endswith(filenames(1), ".nc") .and. .not. endswith(fname_out, ".nc")) then
1217 : 0 : fname_out = nctk_ncify(fname_out)
1218 : 0 : call wrtout(std_out,"- Added .nc extension to output file as input data is in netcdf format.")
1219 : : end if
1220 : :
1221 : 0 : call ioscr_wremove(filenames(1), hscr_file(1), fname_out, nfreq_tot, freq_indx, hscr_merge)
1222 : :
1223 [ # # ]: 0 : ABI_FREE(freq_indx)
1224 : :
1225 : : case default
1226 : : ! Bail if choice is wrong
1227 : 0 : write(std_out,*) ' Invalid choice! Exiting...'
1228 [ + - - + : 6 : goto 100
- - ]
1229 : : end select
1230 : :
1231 : : end if ! Single file mode
1232 : :
1233 : 16 : call timein(tcpu,twall)
1234 : :
1235 : 16 : tsec(1)=tcpu-tcpui
1236 : 16 : tsec(2)=twall-twalli
1237 : :
1238 : 16 : write(std_out, '(a,a,a,f13.1,a,f13.1)' ) '-',ch10,'- Proc. 0 individual time (sec): cpu=',tsec(1),' wall=',tsec(2)
1239 : :
1240 : : ! Free memory
1241 [ - + ]: 16 : ABI_FREE(filenames)
1242 [ - + - - ]: 16 : ABI_SFREE(kxcg)
1243 [ + - - + ]: 16 : ABI_SFREE(foundq)
1244 : :
1245 : 16 : call cryst%free(); call Kmesh%free(); call Qmesh%free(); call destroy_mpi_enreg(MPI_enreg)
1246 : :
1247 : 16 : nullify(Hscr0)
1248 : 16 : call Hscr_merge%free()
1249 : :
1250 [ + + ]: 48 : do ifile=1,nfiles
1251 : 48 : call Hscr_file(ifile)%free()
1252 : : end do
1253 [ + - + + : 64 : ABI_FREE(Hscr_file)
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - - -
- - - - -
- - - - -
- - - -
+ ]
1254 : :
1255 : 16 : call flush_unit(std_out)
1256 : 16 : call abinit_doctor("__mrgscr")
1257 : :
1258 : 16 : 100 call xmpi_end()
1259 : :
1260 : 64 : end program mrgscr
1261 : : !!***
|