Branch data Line data Source code
1 : : !!****p* ABINIT/lruj
2 : : !! NAME
3 : : !! lruj
4 : : !!
5 : : !! FUNCTION
6 : : !! Linear Response U and J:
7 : : !! Determines Hubbard U or Hund's J from series of *DS*_LRUJ.nc
8 : : !! files containing information regarding the perturbation applied to a particular
9 : : !! atom and the resulting occupations/magnetizations. The procedure implemented
10 : : !! is that of the SCF linear response for the Hubbard U (Phys. Rev. B 71,035105)
11 : : !! and the Hund's J (Phys. Rev. B 98, 235157) parameters.
12 : : !! This protocol was coded up in November 2022 by Lorien MacEnulty (macenulty.com),
13 : : !! doctoral researcher in the Quantum Theory of Materials group (theoryofmaterials.com)
14 : : !! at Trinity College Dublin, headed by Dr. David O'Regan.
15 : : !!
16 : : !! COPYRIGHT
17 : : !! Copyright (C) 1998-2026 ABINIT group (LMac)
18 : : !! This file is distributed under the terms of the
19 : : !! GNU General Public License, see ~abinit/COPYING
20 : : !! or http://www.gnu.org/copyleft/gpl.txt .
21 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
22 : : !!
23 : : !! INPUTS
24 : : !! Executed as ./lruj *LRUJ.nc FILE1 FILE2 FILE3 ... [--d 5] [--help] [--version]
25 : : !! --d <n> = Command line argument: highest degree of intended polynomial fits
26 : : !! *DS*_LRUJ.nc files = gives data from perturbative Abinit calculations
27 : : !!
28 : : !! OUTPUT
29 : : !! std_out = log file
30 : : !!
31 : : !! SOURCE
32 : :
33 : : #if defined HAVE_CONFIG_H
34 : : #include "config.h"
35 : : #endif
36 : :
37 : : #include "abi_common.h"
38 : :
39 : :
40 : 4 : program lruj
41 : :
42 : 4 : use defs_basis
43 : : use m_xmpi
44 : : use m_abicore
45 : : use m_build_info
46 : : use m_errors
47 : : use m_argparse
48 : : use m_crystal
49 : : use netcdf
50 : : use m_nctk
51 : : use m_yaml
52 : :
53 : : use m_fstrings, only : itoa, sjoin, ltoa
54 : : use m_specialmsg, only : specialmsg_getcount, herald
55 : : use m_numeric_tools, only : polynomial_regression
56 : : use m_sort, only : sort_dp
57 : : use m_common, only : crystal_from_file
58 : : use m_mpinfo, only : destroy_mpi_enreg, initmpi_seq
59 : : use m_paw_uj, only : pawuj_ini,pawuj_free,pawuj_det, macro_uj_type
60 : :
61 : : implicit none
62 : :
63 : : !Local variables-------------------------------
64 : :
65 : : !scalars
66 : : integer,parameter :: master=0
67 : : integer :: nproc,my_rank,comm
68 : : logical :: iam_master
69 : :
70 : : integer :: ncid,nnat,natom,prtvol,nargs,nfiles,ndtpawuj,degarg
71 : : integer :: ndata,nspden,macro_uj,pawujat,dmatpuopt
72 : : integer :: degree,mdegree,ii,ipert
73 : : real(dp) :: diem,ph0phiint,signum !diemix, diemixmag,
74 : : type(yamldoc_t) :: ydoc
75 : : !type(crystal_t) :: cryst
76 : :
77 : : !arrays
78 : 4 : integer, allocatable :: iperm(:),pawujat_file(:),macrouj_file(:),dmatpuopt_file(:)
79 : 4 : real(dp), allocatable :: diem_file(:),ph0phiint_file(:),nspden_file(:)
80 : :
81 : 4 : real(dp), allocatable :: perts(:),occs0(:),occs(:)
82 : 4 : real(dp), allocatable :: uj_perts(:),luocc(:,:),luocc_nnat(:,:)
83 : 4 : real(dp), allocatable :: chi0coeffs(:),chicoeffs(:),chi0(:),chi(:),hubpar(:)
84 : 4 : real(dp), allocatable :: chi0err(:),chierr(:),hubparerr(:)
85 : :
86 : : !characters
87 : : character(len=1) :: parname
88 : : character(len=5) :: degreename
89 : : character(len=12) :: regname
90 : : character(len=14) :: occmag
91 : : character(len=24) :: codename
92 : : character(len=30) :: diem_token
93 : : character(len=500) :: message,arg,msg,pertname
94 : 4 : character(len=fnlen),allocatable :: file_paths(:)
95 : :
96 : :
97 : : !##########################################################################################################
98 : : !################################## Set up MPI architecture (unused) ####################################
99 : :
100 : : !Change communicator for I/O (mandatory!)
101 : 4 : call abi_io_redirect(new_io_comm=xmpi_world)
102 : :
103 : : !Initialize MPI (not used but necessary)
104 : 4 : call xmpi_init()
105 : 4 : comm = xmpi_world
106 : 4 : nproc = xmpi_comm_size(comm)
107 : 4 : my_rank = xmpi_comm_rank(comm)
108 : 4 : iam_master = (my_rank == master)
109 : :
110 : : !Initialize memory profiling if it is activated
111 : : !if a full abimem.mocc report is desired, set the argument of abimem_init to "2" instead of "0"
112 : : !note that abimem.mocc files can easily be multiple GB in size so don't use this option normally
113 : : #ifdef HAVE_MEM_PROFILING
114 : : call abimem_init(0)
115 : : #endif
116 : :
117 : : !No MPI functionality needed for main procedure.
118 [ - + ]: 4 : if (my_rank /= master) goto 100
119 : :
120 : : !##########################################################################################################
121 : : !###################################### Read command line options #######################################
122 : :
123 : : !Count arguments and number of files (= #perturbations)
124 : 4 : nargs = command_argument_count()
125 [ + - - + : 4 : ABI_MALLOC(file_paths, (nargs))
- + - + -
+ - + -
+ ]
126 : 4 : nfiles = 0
127 [ + + ]: 22 : do ii=1,nargs
128 : 18 : call get_command_argument(ii, arg)
129 [ - + ]: 18 : if (arg(1:1) == "-") exit
130 : 18 : nfiles = nfiles + 1
131 [ + - + - ]: 22 : file_paths(nfiles) = trim(arg)
132 : : end do
133 : :
134 : : !Assess options
135 [ + + ]: 22 : do ii=1,command_argument_count()
136 : 18 : call get_command_argument(ii, arg)
137 [ - + ]: 22 : if (arg == "--version") then
138 : 0 : write(std_out,"(a)") trim(abinit_version); goto 100
139 [ - + ]: 18 : else if (arg == "-h" .or. arg == "--help") then
140 : : !Document the options.
141 : 0 : call lruj_show_help()
142 : 0 : goto 100
143 : : end if
144 : : end do
145 : :
146 : : !If no files found, exit program.
147 [ - + ]: 4 : if (nfiles == 0) then
148 : 0 : write(std_out, *) "Empty file list!"
149 : 0 : goto 100
150 : : end if
151 : :
152 : : !Get other options from the CLI. e.g. --prtvol 0 -d 3.0
153 : : !Should be documented in lruj_show_help
154 [ - + ]: 4 : ABI_CHECK(get_arg("prtvol", prtvol, msg, default=0) == 0, msg)
155 [ - + ]: 4 : ABI_CHECK(get_arg("d", degarg, msg, default=1) == 0, msg)
156 : :
157 : : !Print header
158 : 4 : codename='LRUJ'//repeat(' ',18)
159 : 4 : call herald(codename, abinit_version, std_out)
160 : :
161 : : !##########################################################################################################
162 : : !###################################### Read *DSi*_LRUJ.nc files ########################################
163 : :
164 [ + - - + : 4 : ABI_MALLOC(uj_perts,(nfiles))
- + - + -
+ - + -
+ ]
165 [ + - - + : 4 : ABI_MALLOC(macrouj_file, (nfiles))
- + - + -
+ - + -
+ ]
166 : :
167 : : !Read perturbation strengths, parameter type, #spins and #atoms
168 : : !from each file.
169 [ + + ]: 22 : do ii=1,nfiles
170 [ - + ]: 18 : NCF_CHECK(nctk_open_read(ncid, file_paths(ii), xmpi_comm_self))
171 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid("uj_pert"), uj_perts(ii)))
172 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid("macro_uj"), macrouj_file(ii)))
173 : 18 : macro_uj=macrouj_file(1)
174 : : !Make sure ndtpawuj is always 4.
175 [ - + ]: 18 : NCF_CHECK(nctk_get_dim(ncid, "ndtpawuj", ndtpawuj))
176 [ - + ]: 18 : ABI_CHECK_IEQ(ndtpawuj, 4, "Wrong ndtpawuj")
177 [ - + ]: 18 : NCF_CHECK(nctk_get_dim(ncid, "nspden", nspden))
178 [ - + ]: 18 : NCF_CHECK(nctk_get_dim(ncid, "nnat", nnat))
179 [ - + ]: 18 : NCF_CHECK(nctk_get_dim(ncid, "natom", natom))
180 [ - + ]: 22 : NCF_CHECK(nf90_close(ncid))
181 : : end do
182 : :
183 : : !Sort files by perturbation magnitude.
184 [ + - - + : 4 : ABI_MALLOC(iperm, (nfiles))
- + - + -
+ - + -
+ ]
185 [ - + + + : 58 : iperm = [(ii, ii=1,nfiles)]
- + + + +
- + - - -
+ + ]
186 : 4 : call sort_dp(nfiles, uj_perts, iperm, tol12)
187 [ - + + + : 40 : file_paths(1:nfiles) = file_paths(iperm(:))
+ + ]
188 [ - + ]: 4 : ABI_FREE(iperm)
189 : :
190 : : !Allocate main data-holding arrays.
191 [ + - - + : 4 : ABI_MALLOC(luocc, (ndtpawuj, nfiles))
+ - - + -
+ - + - +
- + - + ]
192 [ + - - + : 4 : ABI_MALLOC(luocc_nnat, (ndtpawuj, nnat))
+ - - + -
+ - + - +
- + - + ]
193 [ + - - + : 4 : ABI_MALLOC(pawujat_file, (nfiles))
- + - + -
+ - + -
+ ]
194 [ + - - + : 4 : ABI_MALLOC(diem_file, (nfiles))
- + - + -
+ - + -
+ ]
195 [ + - - + : 4 : ABI_MALLOC(dmatpuopt_file, (nfiles))
- + - + -
+ - + -
+ ]
196 [ + - - + : 4 : ABI_MALLOC(ph0phiint_file, (nfiles))
- + - + -
+ - + -
+ ]
197 [ + - - + : 4 : ABI_MALLOC(nspden_file, (nfiles))
- + - + -
+ - + -
+ ]
198 : :
199 : : !Set macro_uj-specific variables, strings and constants.
200 [ + + ]: 4 : if (macro_uj==4) then !Calculation of the Hunds J parameter
201 : 2 : diem_token="diemixmag" !Unscreened response in Hund's J impacted by diemixmag
202 : 2 : pertname='beta ' !Hund's J perturbation: +beta to spin up, -beta to down
203 : 2 : parname='J'
204 : 2 : occmag='Magnetizations' !Magnetic moments are monitored.
205 : 2 : signum=-1.0d0 !Hund's J is -1*(1/chi0-1/chi)
206 : : else
207 : 2 : diem_token="diemix" !Unscreened response in Hubbard U impacted by diemix
208 : 2 : pertname='alpha' !Hubbard U perturbation; applied equally to spins up and down
209 : 2 : parname='U'
210 : 2 : occmag=' Occupations' !Total occupation is monitored.
211 : 2 : signum=1.0d0 !Hubbard U is 1*(1/chi0-1/chi)
212 : : end if
213 : :
214 : : !Allocate perturbation and occupation arrays. Set the first
215 : : !to the unperturbed case (i.e., when perturbation=0.0d0).
216 [ + - - + : 4 : ABI_MALLOC(perts,(0:nfiles))
- + - + -
+ - + -
+ ]
217 [ + - - + : 4 : ABI_MALLOC(occs0,(0:nfiles))
- + - + -
+ - + -
+ ]
218 [ + - - + : 4 : ABI_MALLOC(occs,(0:nfiles))
- + - + -
+ - + -
+ ]
219 : 4 : perts(0)=0.0d0 !Unperturbed case.
220 : :
221 : 4 : write(std_out,'(a,i2)') ' Number of perturbations detected: ',nfiles
222 : :
223 : : !Open _LRUJ.nc files and read in the relevant data.
224 [ + + ]: 22 : do ii=1,nfiles
225 [ - + ]: 18 : NCF_CHECK(nctk_open_read(ncid, file_paths(ii), xmpi_comm_self))
226 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid("pawujat"), pawujat_file(ii)))
227 : 18 : pawujat=pawujat_file(1)
228 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid("nspden"), nspden_file(ii)))
229 : 18 : nspden=nspden_file(1)
230 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid("luocc"), luocc_nnat))
231 [ + + ]: 90 : luocc(:,ii) = luocc_nnat(:,pawujat)
232 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid(diem_token), diem_file(ii)))
233 : 18 : diem=diem_file(1)
234 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid("dmatpuopt"), dmatpuopt_file(ii)))
235 : 18 : dmatpuopt=dmatpuopt_file(1)
236 [ - + ]: 18 : NCF_CHECK(nf90_get_var(ncid, vid("ph0phiint"), ph0phiint_file(ii)))
237 : 18 : ph0phiint=ph0phiint_file(1)
238 [ - + ]: 18 : NCF_CHECK(nf90_close(ncid))
239 : : !Testing if the unperturbed occupancies are equal across each run. If they
240 : : !aren't, then exit. If they are equal, then save them in appropriate arrays.
241 [ - + ]: 22 : if ((ii>1).and.((occs0(0)/=luocc(1,ii)).or.(occs(0)/=luocc(2,ii)))) then
242 : 0 : write(std_out,'(a)') "ERROR: Unperturbed ground state occupations across LRUJ datasets are not equal."
243 : 0 : write(std_out,'(a)') "Check the consistency of input variables in your perturbative calculations:"
244 : 0 : write(std_out,'(a)') " 1. Are they each reading in the same WFK file?"
245 : 0 : write(std_out,'(a)') " 2. Are macro-uj, pawujat, dmatpuopt, diemix(mag) consistent"
246 : 0 : write(std_out,'(a)') " across all perturbations?"
247 : 0 : write(std_out,'(a)') "If not, relaunch perturbative Abinit calculations, then"
248 : 0 : write(std_out,'(2a)') "reexecute lruj utility. Exiting.",ch10
249 : 0 : goto 100
250 : : else
251 : 18 : perts(ii)=uj_perts(ii)*Ha_eV
252 : 18 : occs0(0)=luocc(1,ii)
253 : 18 : occs(0)=luocc(2,ii)
254 : 18 : occs0(ii)=luocc(3,ii)
255 : 18 : occs(ii)=luocc(4,ii)
256 : : end if
257 : : end do
258 : :
259 : : !##########################################################################################################
260 : : !#################################### Tests on input information ########################################
261 : :
262 : : !Tests if we have enough data points (at least 3) to conduct distinct regression.
263 : 4 : ndata=nfiles+1
264 : 4 : write(std_out,'(a,i2,a)') ' Including unperturbed state, we have ',ndata,' data points.'
265 [ - + ]: 4 : if (ndata==0) then
266 : 0 : ABI_ERROR('No linear response data points found.')
267 [ - + ]: 4 : else if (ndata==1) then
268 : : msg = sjoin('Only one data point found. This utility needs',ch10,&
269 : : 'at least three (3) data points (two non-zero perturbations and one unperturbed) to compute',ch10,&
270 [ # # ]: 0 : 'the Hubbard parameter.')
271 : 0 : ABI_ERROR(msg)
272 [ - + ]: 4 : else if (ndata==2) then
273 : : msg = sjoin('Only two data points found. The scalar Hubbard Parameter from',ch10,&
274 : : 'the two-point linear regression scheme has already been printed in your .abo file. Try bashing',ch10,&
275 [ # # ]: 0 : '==> grep "two-point regression" <run_name.abo> ',ch10,'to find the result of this calculation.')
276 : 0 : ABI_ERROR(msg)
277 : : end if
278 : :
279 : : !pawujat consistency check.
280 [ + + - + : 22 : if (any(pawujat_file /= pawujat_file(1))) then
- + ]
281 : : msg = sjoin("Found different values of pawujat in files: ", ltoa(pawujat_file),ch10,&
282 [ # # ]: 0 : "Perturbed atom has to be consistent across perturbations to compute U or J.")
283 : 0 : ABI_ERROR(msg)
284 : : end if
285 : :
286 : : !dmatpuopt consistency check
287 [ + + - + : 22 : if (any(dmatpuopt_file /= dmatpuopt_file(1))) then
- + ]
288 : : msg = sjoin("Found different values of dmatpuopt in files: ", ltoa(dmatpuopt_file),ch10,&
289 [ # # ]: 0 : "PAW projector must be consistent across perturbations to compute U or J.")
290 : 0 : ABI_ERROR(msg)
291 : : end if
292 : :
293 : : !macro_uj consistency check
294 [ + + - + : 22 : if (any(macrouj_file /= macrouj_file(1))) then
- + ]
295 : : msg = sjoin("Found different values of macro_uj in files: ",ltoa(macrouj_file),ch10,&
296 [ # # ]: 0 : "Perturbation protocol and occupancy monitoring must be consistent to compute U or J.")
297 : 0 : ABI_ERROR(msg)
298 : : end if
299 : :
300 : : !diemix/diemixmag consistency check
301 [ + + - + : 22 : if (any(diem_file /= diem_file(1))) then
- + ]
302 : : msg = sjoin("Found different values of mixing constant in files: ",ltoa(diem_file),ch10,&
303 [ # # ]: 0 : "Unscreened response functions will factor into U (J) incorrectly.")
304 : 0 : ABI_ERROR(msg)
305 : : end if
306 : :
307 : : !Tests consistency of macro_uj, then writes message about macro_uj procedure selected.
308 : : !Also assigns Hubbard parameter-specific variables.
309 [ - + ]: 4 : if (nspden==1) then
310 : 0 : write(message,'(a)') ' Determination of U-parameter for unpolarized structure (non standard)'
311 [ + + ]: 4 : else if (macro_uj==1.and.nspden==2) then
312 : 2 : write(message,'(a)') ' Standard determination of the Hubbard U parameter.'
313 [ - + ]: 2 : else if (macro_uj==2.and.nspden==2) then
314 : 0 : write(message,'(a)') ' Determination of parameter on single spin channel (experimental)'
315 : 0 : pertname='Pert. '
316 [ - + ]: 2 : else if (macro_uj==3.and.nspden==2) then
317 : 0 : parname='J'
318 : 0 : pertname='Pert. '
319 : 0 : write(message,'(a)') ' Determination of (not Hunds) J-parameter on single spin channel (experimental)'
320 [ + - ]: 2 : else if (macro_uj==4.and.nspden==2) then
321 : 2 : write(message,'(a)') ' Hunds J determination, implemented by L. MacEnulty August 2021'
322 : : end if
323 : 4 : call wrtout(std_out,message)
324 : :
325 : : !Tests compatibility of nspden and macro_uj
326 [ - + ]: 4 : if (macro_uj>1.and.nspden==1) then
327 : : msg = sjoin('U on a single spin channel (or J) can only be determined for nspden=2 ,',ch10,&
328 [ # # ]: 0 : 'Cannot calculate the chosen Hubbard parameter.')
329 : 0 : ABI_ERROR(msg)
330 : : end if
331 : :
332 : : !Tests if perturbations are too small.
333 [ + - - + : 26 : if (maxval(abs(uj_perts))<0.00000001) then
- - + + +
+ - + ]
334 : : msg = sjoin('Perturbation magnitudes are too small.',ch10,&
335 [ # # ]: 0 : 'Rerun perturbative Abinit calculations with pawujv >> 1d-8.')
336 : 0 : ABI_ERROR(msg)
337 : : end if
338 : :
339 : : !##########################################################################################################
340 : : !############################### Calculation of the Response Functions ##################################
341 : :
342 : : !Test compatibility of polynomial degree (if present as an argument) with
343 : : !number of data points. Otherwise, default to the following:
344 : : !If we have 3 data points, conduct at maximum a linear regression.
345 : : !If 4 data points, conduct linear and quadratic regressions.
346 : : !If more than 5 data points, conduct linear, quadratic and cubic regressions.
347 [ - + ]: 4 : if (degarg/=1) then
348 [ # # ]: 0 : if (degarg>ndata-2) then
349 : 0 : write(std_out,'(4a,i2,3a,i2,2a)') ch10,' ERROR: Your chosen polynomial degree is too large. The resulting',ch10,&
350 : 0 : & ' parameters will certainly be overfitted. Either conduct ',degarg+1,' perturbations,',ch10,&
351 : 0 : & ' or execute this utility again with --d',ndata-2,' or smaller. Exiting program.',ch10
352 : 0 : goto 100
353 : : else
354 : 0 : mdegree=degarg
355 : : end if
356 : : else !Default max polynomial degree
357 [ - + ]: 4 : if (ndata<=4) then
358 : 0 : mdegree=ndata-2
359 : : else
360 : 4 : mdegree=3
361 : : end if
362 : : end if
363 : 4 : write(std_out,'(a,i2)') ' Maximum degree of polynomials analyzed: ',mdegree
364 : :
365 : : !Write warning about response matrices
366 : 4 : write(std_out,'(5a)') ' NOTE: Unlike the ujdet utility, lruj treats the ',ch10,&
367 : 4 : ' response functions as scalars, not matrices!',ch10,&
368 : 8 : ' See lruj tutorial for more information.'
369 : :
370 : : !Allocate the response and error arrays
371 [ + - - + : 4 : ABI_MALLOC(chi0err,(mdegree))
- + - + -
+ - + -
+ ]
372 [ + - - + : 4 : ABI_MALLOC(chierr,(mdegree))
- + - + -
+ - + -
+ ]
373 [ + - - + : 4 : ABI_MALLOC(chi0,(mdegree))
- + - + -
+ - + -
+ ]
374 [ + - - + : 4 : ABI_MALLOC(chi,(mdegree))
- + - + -
+ - + -
+ ]
375 [ + - - + : 4 : ABI_MALLOC(hubpar,(mdegree))
- + - + -
+ - + -
+ ]
376 [ + - - + : 4 : ABI_MALLOC(hubparerr,(mdegree))
- + - + -
+ - + -
+ ]
377 : :
378 : : !Start to write information in YAML format to plot with AbiPY
379 : 4 : ydoc = yamldoc_open('LRUJ_Abipy_Plots') !, width=11, real_fmt='(3f8.3)')
380 : 4 : call ydoc%add_int("natom",natom)
381 : 4 : call ydoc%add_int("ndata",ndata)
382 : 4 : call ydoc%add_int("pawujat",pawujat)
383 : 4 : call ydoc%add_int("macro_uj",macro_uj)
384 : 4 : call ydoc%add_string("diem_token",diem_token)
385 : 4 : call ydoc%add_real("diem",diem)
386 : :
387 : : !For all regressions, call subroutine to calculate polynomial fit for chi0 and chi.
388 [ + + ]: 16 : do degree=1,mdegree
389 [ + - + - : 12 : ABI_MALLOC(chi0coeffs,(degree+1))
- + - + -
+ - + - +
- + ]
390 [ + - + - : 12 : ABI_MALLOC(chicoeffs,(degree+1))
- + - + -
+ - + - +
- + ]
391 : 12 : call polynomial_regression(degree,ndata,perts,occs0,chi0coeffs,chi0err(degree))
392 : 12 : call polynomial_regression(degree,ndata,perts,occs,chicoeffs,chierr(degree))
393 : :
394 : : !YAML doc information on regression coefficients
395 : 12 : write(message, '(a,i0)' ) 'chi0_coefficients_degree',degree
396 : 12 : call ydoc%add_real1d(message,chi0coeffs)
397 : 12 : write(message, '(a,i0)' ) 'chi_coefficients_degree',degree
398 : 12 : call ydoc%add_real1d(message,chicoeffs)
399 : :
400 : 12 : chi0(degree)=chi0coeffs(2)/diem !The derivative of all polynomial regressions
401 : 12 : chi(degree)=chicoeffs(2) !at pert=0.0 is just the second coefficient.
402 : 12 : chi0err(degree)=chi0err(degree)/diem !Chi0 error divided by diem also.
403 : 12 : hubpar(degree)=signum*(1.0d0/chi0(degree)-1.0d0/chi(degree))
404 : 12 : hubparerr(degree)=sqrt((chi0err(degree)/chi0(degree)**2)**2+(chierr(degree)/chi(degree)**2)**2)
405 [ - + ]: 12 : ABI_FREE(chi0coeffs)
406 [ - + ]: 16 : ABI_FREE(chicoeffs)
407 : : end do
408 : :
409 : : !##########################################################################################################
410 : : !############################# Printing information on Hubbard Parameters ################################
411 : :
412 : : !Printing relevant information about the Hubbard parameter just calculated.
413 : 4 : write(message,'(3a)') ch10,ch10, &
414 : 8 : '*************************************************************************************************'
415 : 4 : call wrtout(std_out,message)
416 : : write(message,'(4a)') &
417 : 4 : '************************************** Linear Response ',parname,' **************************************',ch10
418 : 4 : call wrtout(std_out,message)
419 : 4 : write(message, '(a,i4)' ) ' Total number of atoms: ',natom
420 : 4 : call wrtout(std_out,message)
421 : 4 : write(message, '(a,i4)' ) ' Index of perturbed atom: ',pawujat
422 : 4 : call wrtout(std_out,message)
423 : 4 : write(message, '(a,i4)' ) ' Value of macro_uj: ',macro_uj
424 : 4 : call wrtout(std_out,message)
425 : 4 : write(message, '(a,i4)' ) ' Value of dmatpuopt: ',dmatpuopt
426 : 4 : call wrtout(std_out,message)
427 : 4 : write(message, '(a,f6.3)' ) ' Mixing constant factored out of Chi0: ',diem
428 : 4 : call wrtout(std_out,message)
429 : : write(message, '(a,f12.5,2a)' )&
430 : 4 : ' Percentage of AE orbital within the PAW sphere of perturbed subspace: ',ph0phiint*100.00,'%',ch10
431 : 4 : call wrtout(std_out,message)
432 : :
433 : 4 : write(message, fmt='(10a)')' Perturbations ',occmag,ch10,&
434 : 4 : ' --------------- -----------------------------',ch10,&
435 [ + - ]: 4 : ' ',trim(pertname),' [eV] Unscreened Screened',ch10,&
436 : 8 : ' --------------- -----------------------------'
437 : 4 : call wrtout(std_out,message)
438 [ + + ]: 22 : do ipert=1,nfiles
439 [ + + ]: 18 : if ((perts(ipert)>0.0d0).and.(perts(ipert-1)<0.0d0)) then
440 : 4 : write(message, fmt='(3f15.10)') perts(0),occs0(0),occs(0)
441 : 4 : call wrtout(std_out,message)
442 : : end if
443 : 18 : write(message, fmt='(3f15.10)') perts(ipert),occs0(ipert),occs(ipert)
444 : 22 : call wrtout(std_out,message)
445 : : end do
446 : :
447 : 4 : write(message, fmt='(11a)') ' RMS Errors',&
448 : 4 : ch10,' ---------------------------------------',ch10,&
449 : 4 : ' Regression Chi0 [eV^-1] Chi [eV^-1] ',parname,' [eV] | Chi0 [eV^-1] Chi [eV^-1] ',parname,&
450 : 8 : ' [eV]',ch10,'--------------------------------------------------------|---------------------------------------'
451 : 4 : call wrtout(std_out,message)
452 [ + + ]: 16 : do degree=1,mdegree
453 [ + + ]: 12 : if (degree==1) then
454 : 4 : regname=' Linear: '
455 [ + + ]: 8 : else if (degree==2) then
456 : 4 : regname=' Quadratic: '
457 [ + - ]: 4 : else if (degree==3) then
458 : 4 : regname=' Cubic: '
459 : : else
460 : 0 : write(degreename,'(i2)') degree
461 [ # # # # ]: 0 : regname=' Degree'//trim(degreename)//' : '
462 : : end if
463 : 12 : write(message,fmt='(a,3f14.7,a,3f13.7)') regname,chi0(degree),chi(degree),hubpar(degree),&
464 : 24 : ' |',chi0err(degree),chierr(degree),hubparerr(degree)
465 : 16 : call wrtout(std_out,message)
466 : : end do
467 : :
468 : : write(message,'(3a)') &
469 : 4 : '*************************************************************************************************',ch10,&
470 : 8 : '*************************************************************************************************'
471 : 4 : call wrtout(std_out,message)
472 : :
473 : :
474 : : !##########################################################################################################
475 : : !############################################ Deallocations ##############################################
476 : :
477 : :
478 [ - + ]: 4 : ABI_FREE(perts)
479 [ - + ]: 4 : ABI_FREE(occs0)
480 [ - + ]: 4 : ABI_FREE(occs)
481 [ - + ]: 4 : ABI_FREE(luocc_nnat)
482 [ - + ]: 4 : ABI_FREE(pawujat_file)
483 [ - + ]: 4 : ABI_FREE(diem_file)
484 [ - + ]: 4 : ABI_FREE(dmatpuopt_file)
485 [ - + ]: 4 : ABI_FREE(ph0phiint_file)
486 [ - + ]: 4 : ABI_FREE(macrouj_file)
487 [ - + ]: 4 : ABI_FREE(nspden_file)
488 [ - + ]: 4 : ABI_FREE(chi0err)
489 [ - + ]: 4 : ABI_FREE(chierr)
490 [ - + ]: 4 : ABI_FREE(chi0)
491 [ - + ]: 4 : ABI_FREE(chi)
492 [ - + ]: 4 : ABI_FREE(hubpar)
493 [ - + ]: 4 : ABI_FREE(hubparerr)
494 [ - + ]: 4 : ABI_FREE(luocc)
495 [ - + ]: 4 : ABI_FREE(uj_perts)
496 [ - + ]: 4 : ABI_FREE(file_paths)
497 : :
498 : : !Ending herald.
499 : 4 : write(std_out,*) ch10,'Linear Response UJ (LRUJ) program complete. Live long and prosper. ~LMac',ch10
500 : :
501 : 4 : call ydoc%write_and_free(std_out)
502 : :
503 : : ! Writes information on file about the memory before ending mpi module, if memory profiling is enabled
504 : 4 : call abinit_doctor("__lruj")
505 : :
506 : 4 : 100 call xmpi_end()
507 : :
508 : : !##########################################################################################################
509 : : !##################################### Subroutines and Functions ########################################
510 : :
511 : : contains
512 : :
513 : : ! Show command line help
514 : 0 : subroutine lruj_show_help()
515 : :
516 : 0 : write(std_out,"(a)")" "
517 : 0 : write(std_out,"(a)")" Linear Response Hubbard U and Hund's J (LRUJ) Utility"
518 : 0 : write(std_out,"(a)")"-----------------------------------------------------------------------------"
519 : 0 : write(std_out,"(a)")"To execute the LRUJ utility, execute: "
520 : 0 : write(std_out,"(a)")" ./lruj FILE1 FILE2 FILE3 ... [options]"
521 : 0 : write(std_out,"(2a)")" ^ input files must be _LRUJ.nc from Abinit run",ch10
522 : 0 : write(std_out,"(a)")" --version Show version number and exit."
523 : 0 : write(std_out,"(a)")" -h, --help Show this help and exit."
524 : 0 : write(std_out,"(a)")" --d <n> Set the maximum degree n polynomial calculated for"
525 : 0 : write(std_out,"(a)")" the response functions chi and chi0."
526 : 0 : write(std_out,"(a)")" (i.e., 1=linear, 2=quadratic, 3=cubic, etc.)"
527 : 0 : write(std_out,"(a)")" NOTE: a degree n polynomial will require at minimum"
528 : 0 : write(std_out,"(a)")" n+2 points (n+1 perturbations and the unperturbed"
529 : 0 : write(std_out,"(a)")" case) or more so as to avoid overfitting."
530 : :
531 : 4 : end subroutine lruj_show_help
532 : :
533 : : ! Function to simplify reading in of variables from netcdf files.
534 : 144 : integer function vid(vname)
535 : : character(len=*),intent(in) :: vname
536 : 288 : vid = nctk_idname(ncid, vname)
537 : 144 : end function vid
538 : :
539 : : end program lruj
540 : : !!***
|