Line data Source code
1 : !!****m* ABINIT/m_paw_uj
2 : !! NAME
3 : !! m_paw_uj
4 : !!
5 : !! FUNCTION
6 : !! This module contains several routines relevant only for automatic determination of U
7 : !! in PAW+U context (linear response method according to Phys. Rev. B 71, 035105)
8 : !!
9 : !! COPYRIGHT
10 : !! Copyright (C) 2018-2026 ABINIT group (DJA)
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 : !!
15 : !! SOURCE
16 :
17 : #if defined HAVE_CONFIG_H
18 : #include "config.h"
19 : #endif
20 :
21 : #include "abi_common.h"
22 :
23 : MODULE m_paw_uj
24 :
25 : use defs_basis
26 : use m_abicore
27 : use m_errors
28 : use m_linalg_interfaces
29 : use m_xmpi
30 : use m_dtset
31 : use netcdf
32 : use m_nctk
33 :
34 : use m_fstrings, only : strcat
35 : use m_pptools, only : prmat
36 : use m_special_funcs, only : iradfnh
37 : use m_geometry, only : shellstruct,ioniondist
38 : use m_parser, only : prttagm
39 : use m_supercell, only : mksupercell
40 : use m_pawrad, only : pawrad_type
41 : use m_pawtab, only : pawtab_type
42 : use m_paw_ij, only : paw_ij_type
43 : use m_paral_atom, only : get_my_atmtab, free_my_atmtab
44 : use m_dtfil, only : datafiles_type
45 : use m_crystal, only : crystal_t
46 :
47 : implicit none
48 :
49 : private
50 : !!***
51 :
52 : !----------------------------------------------------------------------
53 :
54 : !!****t* m_paw_uj/macro_uj_type
55 : !! NAME
56 : !! dtmacro_uj
57 : !!
58 : !! FUNCTION
59 : !! This data type contains the potential shifts and the occupations
60 : !! for the determination of U and J for the DFT+U calculations.
61 : !! iuj=1,3: non-selfconsistent calculations. iuj=2,4 selfconsistent calculations.
62 : !!
63 : !! SOURCE
64 :
65 : type, public :: macro_uj_type
66 :
67 : ! Integer
68 : integer :: iuj ! dataset treated
69 : integer :: nat ! number of atoms U (J) is determined on
70 : integer :: ndtset ! total number of datasets
71 : integer :: nspden ! number of densities treated
72 : integer :: macro_uj ! which mode the determination runs in
73 : integer :: pawujat ! which atom U (J) is determined on
74 : integer :: pawprtvol ! controlling amount of output
75 : integer :: option ! controls the determination of U (1 with compensating charge bath, 2 without)
76 : integer :: dmatpuopt ! controls the renormalisation of the PAW projectors
77 :
78 : ! Real
79 : real(dp) :: diemix ! mixing parameter
80 : real(dp) :: diemixmag ! magnetic mixing parameter
81 : real(dp) :: mdist ! maximal distance of ions
82 : real(dp) :: pawujga ! gamma for inversion of singular matrices
83 : real(dp) :: ph0phiint ! integral of phi(:,1)*phi(:,1)
84 : real(dp) :: pawujrad ! radius to which U should be extrapolated.
85 : real(dp) :: pawrad ! radius of the paw atomic data
86 :
87 : ! Integer arrays
88 : integer , allocatable :: scdim(:)
89 : ! size of supercell
90 :
91 : ! Real arrays
92 : real(dp) , allocatable :: occ(:,:)
93 : ! occupancies after a potential shift: occ(ispden,nat)
94 :
95 : real(dp) , allocatable :: rprimd(:,:)
96 : ! unit cell for symmetrization
97 :
98 : real(dp) , allocatable :: vsh(:,:)
99 : ! potential shifts on atoms, dimensions: nspden,nat
100 :
101 : real(dp) , allocatable :: xred(:,:)
102 : ! atomic position for symmetrization
103 :
104 : real(dp) , allocatable :: wfchr(:)
105 : ! wfchr(1:3): zion, n and l of atom on which projection is done
106 : ! wfchr(4:6): coefficients ai of a0+a1*r+a2*r^2, fit to the wfc for r< r_paw
107 :
108 : real(dp), allocatable :: zioneff(:)
109 : ! zioneff(ij_proj), "Effective charge"*n "seen" at r_paw, deduced from Phi at r_paw, n:
110 : ! pricipal quantum number; good approximation to model wave function outside PAW-sphere through
111 :
112 : end type macro_uj_type
113 : !!***
114 :
115 : !public procedures.
116 : public :: pawuj_ini ! Initialize dtpawuj datastructure
117 : public :: pawuj_free ! Deallocate dtpawuj datastructure
118 : public :: pawuj_det ! Determine U (or J) parameter
119 : public :: pawuj_red ! Store atomic occupancies, potential shift, positions
120 :
121 : !private procedures.
122 : ! chiscwrt: distributes values of chi_org on chi_sc according to ion-ion distances
123 : ! linvmat: inverts real matrix inmat
124 : ! lprtmat: prints out the real matrix mmat
125 : ! lcalcu: prints out real the real matrice mmat
126 : ! blow_pawuj: reads a real nxn matrice and appends lines n+1 and clumn n+1
127 :
128 : CONTAINS !========================================================================================
129 : !!***
130 :
131 : !----------------------------------------------------------------------
132 :
133 : !!****f* m_paw_uj/pawuj_ini
134 : !! NAME
135 : !! pawuj_ini
136 : !!
137 : !! FUNCTION
138 : !! Initialize dtpawuj datastructure for one SCF run
139 : !! Relevant only for automatic determination of U in PAW+U context
140 : !!
141 : !! INPUTS
142 : !!
143 : !! OUTPUT
144 : !!
145 : !! SIDE EFFECTS
146 : !! dtpawuj(0:ndtpawuj) (initialization of fields vsh, occ, iuj,nnat)
147 : !!
148 : !! SOURCE
149 :
150 10 : subroutine pawuj_ini(dtpawuj,ndtset)
151 :
152 : !Arguments ------------------------------------
153 : !scalars
154 : integer :: ndtset
155 : type(macro_uj_type),intent(inout) :: dtpawuj(0:ndtset)
156 :
157 : !Local variables -------------------------
158 : !Variables for partial dos calculation
159 : !scalars
160 : integer, parameter :: nwfchr=6
161 : integer :: iuj,im1
162 : ! *********************************************************************
163 :
164 : DBG_ENTER("COLL")
165 60 : do iuj=0,ndtset
166 : !write(std_out,*)'pawuj_ini iuj ',iuj
167 50 : dtpawuj(iuj)%diemix=0.45_dp
168 50 : dtpawuj(iuj)%diemixmag=0.45_dp
169 50 : dtpawuj(iuj)%iuj=0
170 50 : dtpawuj(iuj)%nat=0
171 50 : dtpawuj(iuj)%ndtset=1
172 50 : dtpawuj(iuj)%nspden=1
173 50 : dtpawuj(iuj)%macro_uj=0
174 50 : dtpawuj(iuj)%option=1
175 50 : dtpawuj(iuj)%pawujat=1
176 50 : dtpawuj(iuj)%pawujga=one
177 50 : dtpawuj(iuj)%pawprtvol=1
178 50 : dtpawuj(iuj)%ph0phiint=one
179 50 : dtpawuj(iuj)%dmatpuopt=2
180 50 : dtpawuj(iuj)%pawujrad=3.0_dp
181 50 : dtpawuj(iuj)%pawrad=20.0_dp
182 : !Allocate arrays
183 : !write(std_out,*)'pawuj_ini before arrays'
184 50 : ABI_MALLOC(dtpawuj(iuj)%rprimd,(3,3))
185 50 : ABI_MALLOC(dtpawuj(iuj)%scdim,(3))
186 50 : ABI_MALLOC(dtpawuj(iuj)%wfchr,(nwfchr))
187 700 : dtpawuj(iuj)%rprimd=reshape((/ 1,0,0,0,1,0,0,0,1/),(/ 3,3 /))
188 250 : dtpawuj(iuj)%scdim=reshape((/ 250,0,0 /),(/3 /))
189 400 : dtpawuj(iuj)%wfchr=(/ (0,im1=1,nwfchr) /)
190 60 : if (iuj>0) then
191 40 : dtpawuj(iuj)%iuj=-1
192 : end if
193 : end do
194 :
195 : DBG_EXIT("COLL")
196 :
197 10 : end subroutine pawuj_ini
198 : !!***
199 :
200 : !----------------------------------------------------------------------
201 :
202 : !!****f* m_paw_uj/pawuj_free
203 : !! NAME
204 : !! pawuj_free
205 : !!
206 : !! FUNCTION
207 : !! deallocate pawuj stuff
208 : !!
209 : !! INPUTS
210 : !!
211 : !! OUTPUT
212 : !!
213 : !! SOURCE
214 :
215 50 : subroutine pawuj_free(dtpawuj)
216 :
217 : !Arguments -------------------------------
218 : type(macro_uj_type),intent(inout) :: dtpawuj
219 :
220 : ! *********************************************************************
221 :
222 50 : if (allocated(dtpawuj%scdim)) then
223 50 : ABI_FREE(dtpawuj%scdim)
224 : end if
225 50 : if (allocated(dtpawuj%occ)) then
226 50 : ABI_FREE(dtpawuj%occ)
227 : end if
228 50 : if (allocated(dtpawuj%rprimd)) then
229 50 : ABI_FREE(dtpawuj%rprimd)
230 : end if
231 50 : if (allocated(dtpawuj%vsh)) then
232 50 : ABI_FREE(dtpawuj%vsh)
233 : end if
234 50 : if (allocated(dtpawuj%xred)) then
235 50 : ABI_FREE(dtpawuj%xred)
236 : end if
237 50 : if (allocated(dtpawuj%wfchr)) then
238 50 : ABI_FREE(dtpawuj%wfchr)
239 : end if
240 50 : if (allocated(dtpawuj%zioneff)) then
241 0 : ABI_FREE(dtpawuj%zioneff)
242 : end if
243 :
244 50 : end subroutine pawuj_free
245 : !!***
246 :
247 : !----------------------------------------------------------------------
248 : !!****f* m_paw_uj/pawuj_det
249 : !! NAME
250 : !! pawuj_det
251 : !!
252 : !! FUNCTION
253 : !! From the complete dtpawuj-dataset determines U (or J) parameter for
254 : !! PAW+U calculations
255 : !! Relevant only for automatic determination of Hubbard Parameters in
256 : !! PAW+U context.
257 : !! Hubbard U = diemix/chi0-1/chi
258 : !! Hund's J = 1/chi-diemixmag/chi0
259 : !!
260 : !! INPUTS
261 : !! dtpawuj=potential shifts (vsh) and atomic occupations (occ)
262 : !!
263 : !! OUTPUT
264 : !! only printing
265 : !! (among other things a section in the ab.out that can be used for input in ujdet)
266 : !!
267 : !! SOURCE
268 :
269 10 : subroutine pawuj_det(dtpawuj,ndtpawuj,dtset,dtfil,ures,comm)
270 :
271 : !Arguments ------------------------------------
272 : !scalars
273 : !arrays
274 : integer :: ndtpawuj, comm
275 : type(macro_uj_type),intent(in) :: dtpawuj(0:ndtpawuj)
276 : type(dataset_type),intent(in) :: dtset
277 : type(datafiles_type),intent(in) :: dtfil
278 : real(dp),intent(out) :: ures
279 :
280 : !Local variables-------------------------------
281 : !scalars
282 : integer,parameter :: natmax=2,nwfchr=6
283 : integer :: ii,jj,nat_org,natom,jdtset,nspden,macro_uj,marr
284 : integer :: im1,ndtuj,nsh_org, nsh_sc,nat_sc,maxnat
285 : integer :: pawujat,pawprtvol,pawujoption
286 : integer :: dmatpuopt,invopt,ipert
287 : integer :: my_rank, ncid, ncerr
288 : real(dp) :: pawujga,ph0phiint,intg,fcorr,eyp
289 : real(dp) :: diem,signum,scalarHP !LMac quantities
290 :
291 : character(len=500) :: message
292 : !character(len=2) :: hstr
293 : character(len=5) :: pertname
294 : character(len=1) :: parname
295 : character(len=14) :: occmag
296 520 : type(crystal_t) :: cryst
297 : !arrays
298 : integer :: ext(3)
299 20 : real(dp) :: rprimd_sc(3,3),vsh(ndtpawuj),a(5),b(5)
300 10 : integer,allocatable :: jdtset_(:),smult_org(:),smult_sc(:),intmagv_org(:),intmagv_sc(:)
301 10 : real(dp),allocatable :: luocc(:,:),xred_org(:,:)
302 10 : real(dp),allocatable :: magv_org(:),magv_sc(:),chi(:),chi0(:),chi0_sc(:), chi_sc(:), xred_sc(:,:)
303 10 : real(dp),allocatable :: sdistv_org(:),sdistv_sc(:),distv_org(:),distv_sc(:)
304 : integer,parameter :: ncid0 = 0, master = 0
305 : integer :: units(2)
306 : ! *********************************************************************
307 :
308 : DBG_ENTER("COLL")
309 :
310 10 : my_rank = xmpi_comm_rank(comm)
311 30 : units = [std_out, ab_out]
312 :
313 : !write(std_out,*) 'pawuj 01'
314 : !###########################################################
315 : !### 01. Allocations
316 :
317 : !Initializations
318 60 : ndtuj=count(dtpawuj(:)%iuj/=-1)-1 ! number of datasets initialized by pawuj_red
319 30 : ABI_MALLOC(jdtset_,(0:ndtuj))
320 110 : jdtset_(0:ndtuj)=pack(dtpawuj(:)%iuj,dtpawuj(:)%iuj/=-1)
321 60 : jdtset=maxval(dtpawuj(:)%iuj)
322 :
323 : !DEBUG
324 10 : write(message,'(10(a,i3))')'pawuj_det jdtset ',jdtset,&
325 20 : & ' ndtuj ', ndtuj,' ndtpawuj ',ndtpawuj
326 10 : call wrtout(std_out,message,'COLL')
327 : !call flush_unit(6)
328 : !END DEBUG
329 :
330 10 : nspden=dtpawuj(jdtset)%nspden
331 10 : nat_org=dtpawuj(jdtset)%nat
332 10 : natom=dtset%natom
333 10 : write(message,'(a,i3)')'natom,nat_org',nat_org
334 10 : call wrtout(std_out,message,'COLL')
335 : ! ABI_CHECK(nat_org == 1, "MG: I'm not sure we access data with the right index if nat_org > 1")
336 :
337 10 : macro_uj=dtpawuj(jdtset)%macro_uj
338 10 : pawujat=dtpawuj(jdtset)%pawujat
339 10 : pawprtvol=dtpawuj(jdtset)%pawprtvol
340 10 : pawujga=dtpawuj(jdtset)%pawujga
341 10 : pawujoption=dtpawuj(jdtset)%option
342 10 : ph0phiint=dtpawuj(jdtset)%ph0phiint
343 10 : dmatpuopt=dtpawuj(jdtset)%dmatpuopt
344 10 : marr=maxval((/ 9, nspden*nat_org ,nat_org*3 /))
345 10 : eyp=2.5_dp ! for dmatpuopt==2 and 3
346 10 : if (dmatpuopt==1) eyp=eyp+3.0_dp
347 10 : if (dmatpuopt>=3) eyp=(eyp+3.0_dp-dmatpuopt)
348 :
349 : !DEBUG
350 10 : write(message,'(a,i3)')'pawujdet dmatpuopt',dmatpuopt
351 10 : call wrtout(std_out,message,'COLL')
352 : !END DEBUG
353 :
354 40 : ABI_MALLOC(luocc,(ndtpawuj,nat_org))
355 30 : ABI_MALLOC(magv_org,(nat_org))
356 30 : ABI_MALLOC(intmagv_org,(nat_org))
357 30 : ABI_MALLOC(xred_org,(3,nat_org))
358 20 : ABI_MALLOC(chi0,(nat_org))
359 20 : ABI_MALLOC(chi,(nat_org))
360 20 : ABI_MALLOC(distv_org,(nat_org))
361 : !DEBUG
362 : !write(message,fmt='((a,i3,a))')'pawuj_det init sg'
363 : !call wrtout(std_out,message,'COLL')
364 : !END DEBUG
365 85 : luocc=zero
366 :
367 : !###########################################################
368 : !### 02. Testing consistency of parameters and outputting info
369 :
370 : !LMac
371 : ! if (ndtuj/=4) return
372 :
373 10 : write(message, '(3a)' ) ch10,' ---------- calculate U, (J) start ---------- ',ch10
374 10 : call wrtout(ab_out,message,'COLL')
375 :
376 : !Tests if perturbed atom is consistent with ujdet atom
377 50 : if (all(dtpawuj(1:ndtpawuj)%pawujat==pawujat)) then
378 10 : write (message,fmt='(a,i3)') ' All pawujat ok and equal to ',pawujat
379 10 : call wrtout(ab_out,message,'COLL')
380 : else
381 0 : write (message,fmt='(a,4i3,2a)') ' Differing values of pawujat were found: ',dtpawuj(1:ndtuj)%pawujat,ch10,&
382 0 : & 'No determination of U.'
383 0 : call wrtout(ab_out,message,'COLL')
384 0 : return
385 : end if
386 :
387 : !Tests consistency of macro_uj, then writes message about macro_uj procedure selected. LMac
388 10 : if (nspden==1) then
389 0 : write(message,fmt='(2a)') ' nspden==1, determination',&
390 0 : & ' of U-parameter for unpolarized structure (non standard)'
391 10 : else if (macro_uj==1.and.nspden==2) then
392 6 : write(message,fmt='(2a)') ' macro_uj=1 and nspden=2:',&
393 12 : & ' standard determination of Hubbard U-parameter'
394 4 : else if (macro_uj==2.and.nspden==2) then
395 0 : write(message,fmt='(2a)') ' macro_uj=2 and nspden=2:',&
396 0 : & ' determination of parameter on single spin channel (experimental)'
397 4 : else if (macro_uj==3.and.nspden==2) then
398 0 : write(message,fmt='(2a)') ' macro_uj=3 and nspden=2,',&
399 0 : & ' determination of (not Hunds) J-parameter on single spin channel (experimental)'
400 4 : else if (macro_uj==4.and.nspden==2) then
401 4 : write(message,fmt='(2a)') ' macro_uj=4 and nspden=2,',&
402 8 : & ' Hunds J determination -- L. MacEnulty August 2021'
403 : end if
404 10 : call wrtout(ab_out,message,'COLL')
405 :
406 : !Tests compatibility of nspden and macro_uj
407 10 : if (macro_uj>1.and.nspden==1) then
408 0 : write (message,'(4a,2a)') ' U on a single spin channel (or J) can only be determined for nspden=2 ,',ch10,&
409 0 : & 'No determination of U.'
410 0 : call wrtout(ab_out,message,'COLL')
411 0 : return
412 : end if
413 :
414 : !Calculation of response matrix
415 10 : diem=dtpawuj(1)%diemix !Unscreened response in Hubbard U impacted by diemix
416 10 : pertname='alpha' !Hubbard U perturbation; applied equally to spins up and down
417 10 : parname='U'
418 10 : occmag=' Occupations'
419 10 : signum=1.0d0 !Hubbard U is signum*(1/chi0-1/chi)
420 50 : do jdtset=1,4
421 40 : if (nspden==1) then
422 0 : luocc(jdtset,1:nat_org)=dtpawuj(jdtset)%occ(1,:)
423 : !Hubbard U: uses sum of spin up and spin down occupancies
424 40 : else if (macro_uj==1.and.nspden==2) then
425 52 : luocc(jdtset,1:nat_org)=dtpawuj(jdtset)%occ(1,:)+dtpawuj(jdtset)%occ(2,:) !Total occupation
426 16 : else if (macro_uj==2.and.nspden==2) then
427 0 : luocc(jdtset,1:nat_org)=dtpawuj(jdtset)%occ(1,:)
428 16 : else if (macro_uj==3.and.nspden==2) then
429 0 : luocc(jdtset,1:nat_org)=dtpawuj(jdtset)%occ(2,:)
430 0 : parname='J'
431 : !Hund's J: uses difference of spin up and spin down occupancies
432 16 : else if (macro_uj==4.and.nspden==2) then
433 48 : luocc(jdtset,1:nat_org)=dtpawuj(jdtset)%occ(1,:)-dtpawuj(jdtset)%occ(2,:) !Magnetization
434 16 : diem=dtpawuj(1)%diemixmag !Unscreened response in Hund's J impacted by diemixmag
435 16 : pertname='beta ' !Hund's J perturbation: +beta to spin up, -beta to down
436 16 : parname='J'
437 16 : occmag='Magnetizations'
438 16 : signum=-1.0d0 !Hund's J is -1*(1/chi0-1/chi)
439 : end if
440 : ! MG: Cannot use pawujat index to extract vsh as we have used:
441 : !
442 : ! dtpawuj(icyc)%vsh=reshape(pack(atvshift,atvshmusk),(/ nspden,nnat /))
443 :
444 : ! thus the pawujat atom in the atvshift array becomes the first one in %vsh
445 : !
446 : !vsh(jdtset)=dtpawuj(jdtset)%vsh(1,pawujat)
447 40 : vsh(jdtset)=dtpawuj(jdtset)%vsh(1,1)
448 50 : if (pawprtvol==-3) then
449 0 : write(message,fmt='(2a,i3,a,f15.12)') ch10,' Potential shift vsh(',jdtset,') =',vsh(jdtset)
450 0 : call wrtout(std_out,message,'COLL')
451 0 : write(message,fmt='( a,i3,a,120f15.9)') ' Occupations occ(',jdtset,') ',( luocc(jdtset,ii),ii=1,nat_org )
452 0 : call wrtout(std_out,message,'COLL')
453 : end if
454 : end do
455 :
456 10 : write(message,fmt='( a)') 'Occupations assigned.'
457 10 : call wrtout(std_out,message,'COLL')
458 :
459 : !Two-point linear regression of response matrices.
460 35 : chi0=(luocc(1,1:nat_org)-luocc(3,1:nat_org))/(vsh(1)-vsh(3))/diem
461 35 : chi=(luocc(2,1:nat_org)-luocc(4,1:nat_org))/(vsh(2)-vsh(4))
462 :
463 : ! MG: pawujat replaced by 1 because arrays are dimensioned with nat_org (usually 1) and not natom!
464 10 : if ((abs(chi0(1))<0.0000001).or.(abs(chi(1))<0.0000001)) then
465 0 : write(message, '(2a,2f12.5,a)' ) ch10,'Chi0 or Chi is too small for inversion.',&
466 0 : &chi0(1),chi(1),ch10
467 0 : call wrtout(ab_out,message,'COLL')
468 0 : return
469 : end if
470 :
471 : !LMac: Scalar Hubbard Parameter
472 10 : scalarHP=signum*(1.0d0/chi0(1)-1.0d0/chi(1))*Ha_eV
473 :
474 10 : write(message,fmt='(a)')': '
475 10 : if (nspden==2) then
476 35 : magv_org=dtpawuj(1)%occ(1,:)-dtpawuj(1)%occ(2,:)
477 10 : if (all(abs(magv_org)<0.001)) then
478 0 : magv_org=(/(1,im1=1,nat_org)/)
479 : else
480 25 : magv_org=abs(magv_org)/magv_org
481 10 : if (magv_org(1).lt.0) magv_org=magv_org*(-1_dp)
482 10 : if (all(magv_org(2:nat_org).lt.0)) then
483 10 : magv_org=abs(magv_org)
484 5 : write(message,'(a)')', (reset to fm): '
485 : end if
486 : end if
487 : else
488 0 : magv_org=(/(1,im1=1,nat_org)/)
489 : end if
490 65 : intmagv_org=(/(int(magv_org(im1)),im1=1,nat_org)/)
491 :
492 : ! if (pawprtvol==-3) then
493 10 : write(message,fmt='(3a, 150f4.1)') ch10,' Magnetization',trim(message),magv_org
494 10 : call wrtout(std_out,message,'COLL')
495 : ! end if
496 :
497 : !Case of extrapolation to larger r_paw: calculate intg
498 70 : if (all(dtpawuj(1)%wfchr(:)/=0).and.ph0phiint/=1) then
499 10 : if (dtpawuj(1)%pawujrad<20.and.dtpawuj(1)%pawujrad>dtpawuj(1)%pawrad) then
500 : fcorr=(1-ph0phiint)/(IRadFnH(dtpawuj(1)%pawrad,20.0_dp,nint(dtpawuj(1)%wfchr(2)),&
501 10 : & nint(dtpawuj(1)%wfchr(3)),dtpawuj(1)%wfchr(1)))
502 : intg=ph0phiint/(1-fcorr*IRadFnH(dtpawuj(1)%pawujrad,20.0_dp,nint(dtpawuj(1)%wfchr(2)),&
503 10 : & nint(dtpawuj(1)%wfchr(3)),dtpawuj(1)%wfchr(1)))
504 10 : write(message, fmt='(a,f12.5,a,f12.5)') ' pawuj_det: met2 extrapolation to ', dtpawuj(1)%pawujrad,' using factor ',intg
505 10 : call wrtout(std_out,message,'COLL')
506 0 : else if (dtpawuj(1)%pawujrad<dtpawuj(1)%pawrad) then
507 0 : a=0 ; a(1:3)=dtpawuj(1)%wfchr(4:6)
508 0 : a=(/a(1)**2,a(1)*a(2),a(2)**2/3.0_dp+2.0_dp/3.0_dp*a(1)*a(3),a(2)*a(3)/2.0_dp,a(3)**2/5.0_dp/)
509 0 : b=(/(dtpawuj(1)%pawujrad**(im1)-dtpawuj(1)%pawrad**(im1),im1=1,5)/)
510 0 : intg=dot_product(a,b)
511 0 : intg=ph0phiint/(ph0phiint+intg)
512 0 : write(message, fmt='(a,f12.5,a,f12.5)') ' pawuj_det: met1 extrapolation to ', dtpawuj(1)%pawujrad,' using factor ',intg
513 0 : call wrtout(std_out,message,'COLL')
514 0 : else if (dtpawuj(1)%pawujrad==dtpawuj(1)%pawrad) then
515 0 : intg=one
516 0 : write(message, fmt='(a,2i7,3f12.5)') ' pawuj_det: no extrapolation (pawujrad=pawrad)'
517 0 : call wrtout(std_out,message,'COLL')
518 : else
519 0 : intg=ph0phiint
520 0 : write(message, fmt='(a,3f12.5)') ' pawuj_det: extrapolation to r->\inf using factor ',intg
521 0 : call wrtout(std_out,message,'COLL')
522 : end if
523 : else
524 0 : write(message, fmt='(a,2i7,3f12.5)') ' pawuj_det: no extrapolation (ph0phiint=1 or wfchr=0)'
525 0 : call wrtout(std_out,message,'COLL')
526 0 : intg=one
527 : end if
528 :
529 : !Determine U in primitive cell
530 10 : write(message,fmt='(a)')' pawuj_det: determine U in primitive cell'
531 10 : call wrtout(std_out,message,'COLL')
532 :
533 10 : call lcalcu(intmagv_org,nat_org,dtpawuj(1)%rprimd,dtpawuj(1)%xred,chi,chi0,pawujat,ures,pawprtvol,pawujga,pawujoption)
534 : !Begin calculate U in supercell
535 :
536 : !Analyze shell structure of primitive cell
537 : !and atomic distances in primitive cell
538 20 : ABI_MALLOC(smult_org,(nat_org))
539 20 : ABI_MALLOC(sdistv_org,(nat_org))
540 : call shellstruct(dtpawuj(1)%xred,dtpawuj(1)%rprimd,nat_org,&
541 10 : & intmagv_org,distv_org,smult_org,sdistv_org,nsh_org,pawujat,pawprtvol)
542 :
543 :
544 : !LMac: Printing relevant information about the Hubbard parameter just calculated.
545 10 : write(message,'(3a)') ch10,ch10,'*********************************************************************'
546 10 : call wrtout(units,message)
547 10 : write(message,'(4a)') '************************ Linear Response ',parname,' ************************',ch10
548 10 : call wrtout(units,message)
549 10 : write(message, '(a,i4,a)' ) ' Info printed for perturbed atom: ',pawujat,ch10
550 10 : call wrtout(units,message)
551 10 : write(message, fmt='(10a)')' Perturbations ',occmag,ch10,&
552 10 : ' --------------- -----------------------------',ch10,&
553 10 : ' ',pertname,' [eV] Unscreened Screened',ch10,&
554 20 : ' --------------- -----------------------------'
555 10 : call wrtout(units,message)
556 : ! MG: pawujat --> 1.
557 30 : do ipert=1,2
558 20 : write(message, fmt='(3f15.10)') vsh(ipert*2-1)*Ha_eV,luocc(ipert*2-1,1),luocc(ipert*2,1)
559 30 : call wrtout(units,message)
560 : end do
561 10 : write(message,'(2a)') ch10,' Scalar response functions:'
562 10 : call wrtout(units,message)
563 10 : write(message,fmt='(a,f12.5)') ' Chi0 [eV^-1]: ',chi0(1)/Ha_eV
564 10 : call wrtout(units,message)
565 10 : write(message,fmt='(a,f12.5)') ' Chi [eV^-1]: ',chi(1)/Ha_eV
566 10 : call wrtout(units,message)
567 10 : write(message,'(4a,f9.5,a)') ch10,' The scalar ',parname,' from the two-point regression scheme is ',scalarHP,' eV.'
568 10 : call wrtout(units,message)
569 10 : write(message,'(3a)') '*********************************************************************',ch10,&
570 20 : '*********************************************************************'
571 10 : call wrtout(units,message)
572 10 : write(message,'(7a)') 'Note: For more reliable linear regressions of the response',ch10,&
573 10 : 'matrices, it is advised that you have more than two points.',ch10,&
574 20 : 'See the LRUJ protocol for more information.',ch10,ch10
575 10 : call wrtout(std_out,message,'COLL')
576 10 : call wrtout(ab_out,message,'COLL')
577 :
578 : !###########################################################
579 : !### Create the file LRUJ.nc for the LRUJ ujdet utility
580 :
581 10 : if (my_rank == master) then
582 : ! First call:
583 : ! - Create NC file, define dimensions, scalars and arrays.
584 : ! - Add crystal structure and metadata required to post-process the data.
585 10 : NCF_CHECK(nctk_open_create(ncid, strcat(dtfil%filnam_ds(4), "_LRUJ.nc"), xmpi_comm_self))
586 :
587 10 : cryst = dtset%get_crystal(1)
588 10 : NCF_CHECK(cryst%ncwrite(ncid))
589 10 : call cryst%free()
590 :
591 : !Define dimensions.
592 : ncerr = nctk_def_dims(ncid, [ &
593 : nctkdim_t("natom", natom), &
594 : nctkdim_t("nnat", nat_org), &
595 : nctkdim_t("ndtpawuj", ndtpawuj), &
596 : nctkdim_t("nspden", dtset%nspden), &
597 : nctkdim_t("nsppol", dtset%nsppol) ], &
598 60 : defmode=.True.)
599 10 : NCF_CHECK(ncerr)
600 :
601 : ! Define integer scalars
602 : ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: &
603 : "usepaw", "macro_uj", "pawujat", "nspden", "dmatpuopt" &
604 60 : ])
605 :
606 : ! Define double precision scalars
607 : ! @lmacenul: Here I write pawujv so that one can order the results by alpha in the post-processing tool.
608 : ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: &
609 : "diemix", "diemixmag", "ph0phiint", "uj_pert" &
610 50 : ])
611 10 : NCF_CHECK(ncerr)
612 :
613 : ! Define arrays with results.
614 : ! TODO: Here I need an extra dimension to store results with different iuj and/or different names.
615 : ncerr = nctk_def_arrays(ncid, [ &
616 : nctkarr_t("luocc", "dp", "ndtpawuj, nnat") &
617 : !nctkarr_t("vsh", "dp", "nspden, nnat") &
618 20 : ])
619 10 : NCF_CHECK(ncerr)
620 :
621 : ! ===========================================
622 : ! Write metadata that does not depend on icyc
623 : ! ===========================================
624 10 : NCF_CHECK(nctk_set_datamode(ncid))
625 :
626 : ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: &
627 : "usepaw", "macro_uj", "pawujat", "nspden", "dmatpuopt"], &
628 110 : [dtset%usepaw, macro_uj, pawujat, nspden, dmatpuopt])
629 10 : NCF_CHECK(ncerr)
630 :
631 : associate (dt => dtpawuj(1))
632 : ncerr = nctk_write_dpscalars(ncid, [character(len=nctk_slen) :: &
633 : "diemix", "diemixmag", "ph0phiint", "uj_pert" ], &
634 90 : [dt%diemix, dt%diemixmag, ph0phiint, vsh(3)])
635 20 : NCF_CHECK(ncerr)
636 : end associate
637 :
638 : ! Write arrays
639 10 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "luocc"), luocc))
640 :
641 10 : NCF_CHECK(nf90_close(ncid))
642 : end if
643 :
644 10 : ii=1
645 10 : write(message, fmt='(8a)') ' URES ',' ii',' nat',' r_max',' U(J)[eV]',' U_ASA[eV]',' U_inf[eV]',ch10
646 : write(message, fmt='(a,2i7,4f12.5)') &
647 35 : trim(message)//' URES ',ii,nat_org,maxval(abs(distv_org)),signum*ures,signum*ures*exp(log(intg)*eyp),&
648 20 : signum*ures*exp(log(ph0phiint)*eyp)
649 10 : call wrtout(units,message)
650 :
651 10 : if (pawprtvol>1) then
652 0 : write(message,fmt='(a, 150f10.5)')' pawuj_det: ionic distances in original cell (distv_org) ', distv_org
653 0 : call wrtout(std_out,message,'COLL')
654 : end if
655 :
656 : !Construct supercell, calculate limit dimensions of supercell
657 : ii=1
658 40 : maxnat=product(dtpawuj(1)%scdim(:))*nat_org
659 10 : if (maxnat==0) then
660 10 : maxnat=dtpawuj(1)%scdim(1)
661 40 : ext=(/ii, ii, ii/)
662 : else
663 : jj=1
664 0 : do while (jj<=3)
665 0 : ext(jj)=minval( (/ii, dtpawuj(1)%scdim(jj) /) )
666 0 : jj=jj+1
667 : end do
668 : end if
669 40 : ext=ext+(/ 1,1,1 /)
670 10 : ii=ii+1
671 :
672 :
673 40 : nat_sc=product(ext)*nat_org
674 :
675 : !DEBUG
676 : !write(message,fmt='(a,3i4)')'pawuj_det: ext ',ext
677 : !call wrtout(std_out,message,'COLL')
678 : !END DEBUG
679 :
680 55 : do while (nat_sc<=maxnat)
681 135 : ABI_MALLOC(chi0_sc,(nat_sc))
682 90 : ABI_MALLOC(chi_sc,(nat_sc))
683 90 : ABI_MALLOC(distv_sc,(nat_sc))
684 90 : ABI_MALLOC(magv_sc,(nat_sc))
685 135 : ABI_MALLOC(intmagv_sc,(nat_sc))
686 90 : ABI_MALLOC(sdistv_sc,(nat_sc))
687 90 : ABI_MALLOC(smult_sc,(nat_sc))
688 135 : ABI_MALLOC(xred_sc,(3,nat_sc))
689 :
690 : ! Determine positions=xred_sc and supercell dimensions=rpimd_sc
691 : call mksupercell(dtpawuj(1)%xred,intmagv_org,dtpawuj(1)%rprimd,nat_org,&
692 45 : & nat_sc,xred_sc,magv_sc,rprimd_sc,ext,pawprtvol)
693 :
694 : ! Determine shell structure of supercell: multiplicities (smult_sc), radii of shells (sdistv_sc)
695 : ! number of shells (nsh_sc) and atomic distances in supercell (distv_sc)
696 :
697 45 : write(message,fmt='(a,3i3,a)')' pawuj_det: determine shell structure of ',ext(1:3),' supercell'
698 45 : call wrtout(std_out,message,'COLL')
699 :
700 13410 : intmagv_sc=(/(int(magv_sc(im1)),im1=1,nat_sc)/)
701 45 : call shellstruct(xred_sc,rprimd_sc,nat_sc,intmagv_sc,distv_sc,smult_sc,sdistv_sc,nsh_sc,pawujat,pawprtvol)
702 :
703 45 : if (pawprtvol>=2) then
704 0 : write(message,fmt='(a)')' pawuj_det: ionic distances in supercell (distv_sc) '
705 0 : call wrtout(std_out,message,'COLL')
706 0 : call prmat(distv_sc,1,nat_sc,1,std_out)
707 : end if
708 :
709 : ! Determine chi and chi0 in supercell (chi0_sc, chi_sc)
710 : ! DEBUG
711 : ! write(message,fmt='(a)')'pawuj_det: chi and chi0 in supercell'
712 : ! call wrtout(std_out,message,'COLL')
713 : ! END DEBUG
714 :
715 45 : if (pawujoption>2) then
716 0 : invopt=2
717 : else
718 45 : invopt=1
719 : end if
720 :
721 : call chiscwrt(chi0,distv_org,nat_org,sdistv_org,smult_org,nsh_org,&
722 45 : & chi0_sc,distv_sc,nat_sc,smult_sc,nsh_sc,invopt,pawprtvol)
723 : call chiscwrt(chi,distv_org,nat_org,sdistv_org,smult_org,nsh_org,&
724 45 : & chi_sc,distv_sc,nat_sc,smult_sc,nsh_sc,invopt,pawprtvol)
725 :
726 : ! Calculate U in supercell
727 : ! DEBUG
728 : ! write(message,fmt='(a)')'pawuj_det: U in supercell'
729 : ! call wrtout(std_out,message,'COLL')
730 : ! END DEBUG
731 45 : call lcalcu(intmagv_sc,nat_sc,rprimd_sc,xred_sc,chi_sc,chi0_sc,pawujat,ures,pawprtvol,pawujga,pawujoption)
732 4530 : write(message, fmt='(a,2i7,4f12.5)') ' URES ',ii,nat_sc,maxval(abs(distv_sc)),signum*ures,signum*ures*exp(log(intg)*eyp),&
733 90 : & signum*ures*exp(log(ph0phiint)*eyp)
734 45 : call wrtout(units,message)
735 :
736 45 : ABI_FREE(chi0_sc)
737 45 : ABI_FREE(chi_sc)
738 45 : ABI_FREE(distv_sc)
739 45 : ABI_FREE(magv_sc)
740 45 : ABI_FREE(intmagv_sc)
741 45 : ABI_FREE(sdistv_sc)
742 45 : ABI_FREE(smult_sc)
743 45 : ABI_FREE(xred_sc)
744 :
745 180 : if (product(dtpawuj(1)%scdim(:))==0) then
746 180 : ext=(/ii, ii, ii/)
747 : else
748 : jj=1
749 0 : do while (jj<=3)
750 0 : ext(jj)=minval( (/ii, dtpawuj(1)%scdim(jj) /) )
751 0 : jj=jj+1
752 : end do
753 : end if
754 180 : ext=ext+(/ 1,1,1 /)
755 45 : ii=ii+1
756 :
757 280 : nat_sc=product(ext)*nat_org
758 :
759 : end do
760 :
761 10 : write(message, '(3a)' )ch10,' ---------- calculate U, (J) end -------------- ',ch10
762 10 : call wrtout(ab_out,message,'COLL')
763 :
764 10 : ABI_FREE(jdtset_)
765 10 : ABI_FREE(chi)
766 10 : ABI_FREE(chi0)
767 10 : ABI_FREE(smult_org)
768 10 : ABI_FREE(sdistv_org)
769 10 : ABI_FREE(luocc)
770 10 : ABI_FREE(magv_org)
771 10 : ABI_FREE(intmagv_org)
772 10 : ABI_FREE(xred_org)
773 10 : ABI_FREE(distv_org)
774 :
775 : DBG_EXIT("COLL")
776 :
777 30 : end subroutine pawuj_det
778 : !!***
779 :
780 : !----------------------------------------------------------------------
781 : !!****f* m_paw_uj/pawuj_red
782 : !! NAME
783 : !! pawuj_red
784 : !!
785 : !! FUNCTION
786 : !! Store atomic occupancies, potential shift, positions in dtpawuj datastructure.
787 : !!
788 : !! INPUTS
789 : !! istep: SCF iteration step
790 : !! pert_state: 0 if the routine is called with unperturbed occupancies
791 : !! 1 if the routine is called after having applied the perturbation.
792 : !! fatvshift=factor that multiplies atvshift
793 : !! mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
794 : !! comm_atom=--optional-- MPI communicator over atoms
795 : !! my_natom=number of atoms treated by current processor
796 : !! natom=number of atoms in cell
797 : !! ntypat = number of atom types
798 : !! paw_ij(my_natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels
799 : !! pawprtvol= printing volume
800 : !! pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
801 : !! comm=MPI commuicator
802 : !!
803 : !! OUTPUT
804 : !! dtpawuj(0:ndtpawuj) (initialization of fields vsh, occ, occ0, iuj,nnat)
805 : !!
806 : !! SOURCE
807 :
808 146 : subroutine pawuj_red(istep, pert_state, dtfil, &
809 292 : dtset,dtpawuj,fatvshift,my_natom,natom,ntypat,paw_ij,pawrad,pawtab,ndtpawuj, comm, &
810 146 : & mpi_atmtab,comm_atom) ! optional arguments (parallelism)
811 :
812 : !Arguments ------------------------------------
813 : !scalars
814 : integer,intent(in) :: istep, pert_state, my_natom,natom,ntypat,ndtpawuj, comm
815 : integer,optional,intent(in) :: comm_atom
816 : real(dp),intent(in) :: fatvshift
817 : !arrays
818 : integer,optional,target,intent(in) :: mpi_atmtab(:)
819 : type(paw_ij_type),intent(in) :: paw_ij(my_natom)
820 : type(pawtab_type),intent(in) :: pawtab(ntypat)
821 : type(pawrad_type),intent(in) :: pawrad(ntypat)
822 : type(dataset_type),intent(in) :: dtset
823 : type(datafiles_type),intent(in) :: dtfil
824 : type(macro_uj_type),intent(inout) :: dtpawuj(0:ndtpawuj)
825 :
826 : !Local variables-------------------------------
827 : !scalars
828 : integer,parameter :: natmax=2,ncoeff=3, master = 0
829 : integer :: iatom,iatom_tot,ierr,im1,im2,ispden,itypat,ll,nspden,nsppol,iuj,ncyc,icyc
830 : integer :: my_comm_atom,nnat,natpawu,natvshift,pawujat,ndtset,typawujat
831 : !integer :: my_rank, ncid, ncerr
832 : logical :: usepawu !antiferro,
833 : logical :: my_atmtab_allocated,paral_atom
834 : character(len=1000) :: message,hstr
835 : character(len=500) :: messg
836 : !arrays
837 292 : logical :: musk(3,natom)
838 146 : integer,pointer :: my_atmtab(:)
839 : real(dp) :: rrtab(ncoeff),wftab(ncoeff),a(ncoeff,ncoeff),b(ncoeff,ncoeff)! ,a(ncoeff,ncoeff)
840 : real(dp),allocatable :: nnocctot(:,:) !,magv(:)
841 : real(dp),allocatable :: atvshift(:,:,:) ! atvshift(natvshift,2,natom)
842 : logical,allocatable :: dmusk(:,:),atvshmusk(:,:,:) !atvshmusk(natvshift,2,natom)
843 :
844 : ! *********************************************************************
845 :
846 : ABI_UNUSED((/dtfil%ireadwf, istep, pert_state, comm/))
847 :
848 : !Initializations
849 146 : nspden=1;nsppol=1
850 146 : if (my_natom>0) then
851 146 : nspden=paw_ij(1)%nspden ; nsppol=paw_ij(1)%nsppol
852 : end if
853 :
854 : !my_rank = xmpi_comm_rank(comm)
855 :
856 146 : natvshift=dtset%natvshift
857 146 : pawujat=dtset%pawujat
858 146 : natpawu=dtset%natpawu ; ndtset=dtset%ndtset
859 730 : ABI_MALLOC(atvshift,(natvshift,nspden,natom))
860 730 : ABI_MALLOC(atvshmusk,(natvshift,nspden,natom))
861 584 : ABI_MALLOC(dmusk,(nspden,natom))
862 584 : ABI_MALLOC(nnocctot,(nspden,natom))
863 3366 : musk=.false.; dmusk=.false.
864 6272 : atvshift=fatvshift*dtset%atvshift
865 6126 : atvshmusk=.false.
866 1526 : nnocctot=zero
867 146 : typawujat=dtset%typat(pawujat)
868 460 : usepawu=(count(pawtab(:)%usepawu/=0)>0)
869 :
870 : !Set up parallelism over atoms
871 146 : paral_atom=(present(comm_atom).and.(my_natom/=natom))
872 146 : nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
873 146 : my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
874 146 : call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,my_natom_ref=my_natom)
875 :
876 146 : nnat=0
877 146 : if (usepawu) then
878 146 : write(message,'(3a)') ch10, '---------- pawuj_red ------ ',ch10
879 146 : call wrtout(std_out, message,'COLL');
880 606 : do iatom=1,my_natom
881 460 : iatom_tot=iatom;if (paral_atom) iatom_tot=my_atmtab(iatom)
882 460 : itypat=paw_ij(iatom)%itypat;ll=pawtab(itypat)%lpawu
883 606 : if ((ll>=0).and.(pawtab(itypat)%usepawu/=0).and.itypat==typawujat) then
884 832 : musk(:,iatom_tot)=(/.true., .true., .true. /)
885 5200 : atvshmusk(:,:,iatom_tot)=reshape((/ (( (im1==1), im1=1,natvshift) ,im2=1,nspden ) /),(/natvshift,nspden/))
886 624 : do ispden=1,nspden
887 416 : nnocctot(ispden,iatom_tot)=paw_ij(iatom)%nocctot(ispden)
888 624 : dmusk(ispden,iatom_tot)=.true.
889 : end do
890 208 : nnat=nnat+1
891 : end if
892 : end do
893 :
894 : ! Reduction in case of parallelism
895 146 : if (paral_atom) then
896 0 : call xmpi_sum(nnocctot ,my_comm_atom,ierr)
897 0 : call xmpi_lor(atvshmusk,my_comm_atom) ! dim=natpawu ???
898 0 : call xmpi_lor(dmusk ,my_comm_atom)
899 0 : call xmpi_lor(musk ,my_comm_atom)
900 0 : call xmpi_sum(nnat ,my_comm_atom,ierr)
901 : end if
902 :
903 876 : iuj=maxval(dtpawuj(:)%iuj)
904 146 : write(std_out,*)' pawuj_red: iuj',iuj
905 : ! write(std_out,*)' pawuj_red: dtpawuj(:)%iuj ',(dtpawuj(ii)%iuj,ii=1,ndtpawuj)
906 :
907 : !If this is the unperturbed state, then unscreened and screened occupancies
908 : !are the same. Also set perturbation vsh to zero.
909 : !If this is the unperturbed case, then do everything twice; once for iuj=1
910 : !and the same for iuj=2. If this is the perturbed case, do everything only
911 : !once. LMac
912 146 : if (iuj==1) then
913 40 : ABI_MALLOC(dtpawuj(0)%vsh,(nspden,nnat))
914 30 : ABI_MALLOC(dtpawuj(0)%occ,(nspden,nnat))
915 30 : ABI_MALLOC(dtpawuj(0)%xred,(3,nnat))
916 55 : dtpawuj(0)%vsh=0
917 55 : dtpawuj(0)%occ=0
918 70 : dtpawuj(0)%xred=0
919 : ncyc=2
920 : else
921 : ncyc=iuj
922 : end if
923 :
924 302 : do icyc=iuj,ncyc
925 :
926 156 : if (icyc==1) then ! 1 and 3: non-scf steps
927 10 : dtpawuj(icyc+1)%iuj=icyc+1
928 10 : dtpawuj(icyc+2)%iuj=icyc+2
929 146 : else if (icyc==3) then
930 10 : dtpawuj(icyc+1)%iuj=icyc+1
931 : end if
932 :
933 : ! TODO: check that this is correct: this point is passed several times
934 : ! for a given value of iuj - should the stuff be accumulated instead of replaced?
935 156 : if(allocated(dtpawuj(icyc)%vsh)) then
936 116 : ABI_FREE(dtpawuj(icyc)%vsh)
937 : end if
938 624 : ABI_MALLOC(dtpawuj(icyc)%vsh,(nspden,nnat))
939 : !Allocate screened occupancy array: LMac
940 156 : if(allocated(dtpawuj(icyc)%occ)) then
941 116 : ABI_FREE(dtpawuj(icyc)%occ)
942 : end if
943 468 : ABI_MALLOC(dtpawuj(icyc)%occ,(nspden,nnat))
944 156 : if(allocated(dtpawuj(icyc)%xred)) then
945 116 : ABI_FREE(dtpawuj(icyc)%xred)
946 : end if
947 468 : ABI_MALLOC(dtpawuj(icyc)%xred,(3,nnat))
948 :
949 :
950 624 : rrtab=(/0.75_dp,0.815_dp,1.0_dp/)*pawtab(typawujat)%rpaw
951 624 : wftab=pawtab(typawujat)%phi(pawtab(typawujat)%mesh_size,pawtab(typawujat)%lnproju(1))
952 :
953 624 : do im1=1,ncoeff
954 468 : if (pawrad(typawujat)%mesh_type==1) then
955 0 : im2=nint(rrtab(im1)/pawrad(typawujat)%rstep+1)
956 468 : else if (pawrad(typawujat)%mesh_type==2) then
957 468 : im2=nint(log(rrtab(im1)/pawrad(typawujat)%rstep+1)/pawrad(typawujat)%lstep+1)
958 0 : else if (pawrad(typawujat)%mesh_type==3) then
959 0 : im2=nint(log(rrtab(im1)/pawrad(typawujat)%rstep)/pawrad(typawujat)%lstep+1)
960 0 : else if (pawrad(typawujat)%mesh_type==4) then
961 0 : im2=nint(pawtab(typawujat)%mesh_size*(1-exp((-one)*rrtab(im1)/pawrad(typawujat)%rstep))+1)
962 : end if
963 :
964 468 : rrtab(im1)=pawrad(typawujat)%rad(im2)
965 624 : wftab(im1)=pawtab(typawujat)%phi(im2,pawtab(typawujat)%lnproju(1))
966 : end do
967 156 : write(message,fmt='(a,i3,a,10f10.5)')' pawuj_red: mesh_type',pawrad(typawujat)%mesh_type,' rrtab:', rrtab
968 156 : call wrtout(std_out,message,'COLL')
969 156 : write(message,fmt='(a,10f10.5)')' pawuj_red: wftab', wftab
970 156 : call wrtout(std_out,message,'COLL')
971 3432 : a=reshape((/ (( rrtab(im2)**(im1-1), im1=1,3) ,im2=1,3 )/),(/ncoeff,ncoeff/))
972 156 : write(messg,fmt='(a)')'A'
973 156 : call linvmat(a,b,ncoeff,messg,2,0.0_dp,3) ! linvmat(inmat,oumat,nat,nam,option,gam,prtvol)
974 156 : write(std_out,*) 'pawuj_red: a,b ', a,b
975 2028 : wftab=matmul(wftab,b)
976 156 : write(std_out,*) 'pawuj_red: wftab ', wftab
977 624 : dtpawuj(icyc)%wfchr(4:6)=wftab
978 :
979 156 : dtpawuj(icyc)%nat=nnat
980 156 : write(std_out,*) 'pawuj_red: m1'
981 1293 : dtpawuj(icyc)%vsh=reshape(pack(atvshift,atvshmusk),(/ nspden,nnat /))
982 : !factor in next line to compensate nocctot contains just occ of 1 spin channel for nspden=1
983 156 : write(std_out,*) 'pawuj_red: m2'
984 1962 : dtpawuj(icyc)%occ=reshape(pack(nnocctot,dmusk),(/nspden,nnat/))*(3-nspden)
985 156 : write(std_out,*) 'pawuj_red: m3'
986 :
987 825 : write(std_out,*) 'pawuj_red: occ ', dtpawuj(icyc)%occ
988 :
989 1516 : dtpawuj(icyc)%xred=reshape(pack(dtset%xred_orig(:,:,1),musk),(/3,nnat/))
990 156 : dtpawuj(icyc)%ph0phiint=pawtab(typawujat)%ph0phiint(1)
991 : dtpawuj(icyc)%wfchr(1:3)=(/ pawtab(typawujat)%zioneff(1)*(dtset%lpawu(typawujat)+2),&
992 624 : & one*(dtset%lpawu(typawujat)+1),one*(dtset%lpawu(typawujat))/)
993 156 : dtpawuj(icyc)%pawrad=pawtab(typawujat)%rpaw
994 :
995 1092 : write(std_out,*) 'pawuj_red: wfchr ',dtpawuj(icyc)%wfchr
996 :
997 246 : if (icyc.le.2) dtpawuj(icyc)%vsh=0.0d0
998 :
999 156 : write (hstr,'(I0)') icyc
1000 156 : write(message,'(a,a,I3,a)') ch10, '---------- MARK ------ ',icyc,ch10
1001 156 : call wrtout(std_out,message,'COLL')
1002 156 : write(message,fmt='(a)') 'vsh'//trim(hstr)
1003 156 : call wrtout(std_out,message,'COLL')
1004 156 : call prmat(dtpawuj(icyc)%vsh(:,:),1,nnat*nspden,1)
1005 156 : write(message,fmt='(a)') 'occ'//trim(hstr)
1006 156 : call wrtout(std_out,message,'COLL')
1007 156 : call prmat(dtpawuj(icyc)%occ(:,:),1,nnat*nspden,1)
1008 156 : write(message, '(3a)' )'---------- MARK ---------- ',ch10
1009 302 : call wrtout(std_out,message,'COLL')
1010 : end do
1011 : end if !usepawu
1012 :
1013 146 : ABI_FREE(nnocctot)
1014 146 : ABI_FREE(dmusk)
1015 146 : ABI_FREE(atvshift)
1016 146 : ABI_FREE(atvshmusk)
1017 :
1018 : !Destroy atom table used for parallelism
1019 146 : call free_my_atmtab(my_atmtab,my_atmtab_allocated)
1020 :
1021 146 : end subroutine pawuj_red
1022 : !!***
1023 :
1024 : !----------------------------------------------------------------------
1025 :
1026 : !!****f* m_paw_uj/chiscwrt
1027 : !! NAME
1028 : !! chiscwrt
1029 : !!
1030 : !! FUNCTION
1031 : !! PRIVATE ROUTINE
1032 : !! Distributes values of chi_org on chi_sc according to ion-ion distances and multiplicities in shells
1033 : !!
1034 : !! INPUTS
1035 : !! chi_org = response matrix in original unit cell
1036 : !! disv_org = distances (multiplied by magntization) in original unit cell
1037 : !! nat_org = number of atoms in original unit cell
1038 : !! sdisv_org = radii of shells in original unit cell
1039 : !! smult_org = multiplicities of shells in original unit cell
1040 : !! nsh_org = number of shells in original unit cell
1041 : !! disv_sc = distances (multiplied by magntization) in super-cell
1042 : !! nat_sc = number of atoms in super-cell
1043 : !! sdisv_sc = radii of shells in super-cell (was unused, so suppressed)
1044 : !! smult_sc = multiplicities of shells in super-cell
1045 : !! nsh_sc = number of shells in super-cell
1046 : !! opt =
1047 : !!
1048 : !! OUTPUT
1049 : !! chi_sc = first line of reponse matrix in super-cell
1050 : !!
1051 : !! SIDE EFFECTS
1052 : !!
1053 : !! SOURCE
1054 :
1055 90 : subroutine chiscwrt(chi_org,disv_org,nat_org,sdisv_org,smult_org,nsh_org,chi_sc,&
1056 90 : & disv_sc,nat_sc,smult_sc,nsh_sc,opt,prtvol)
1057 :
1058 : !Arguments ------------------------------------
1059 : !scalars
1060 : integer,intent(in) :: nat_org,nsh_org,nsh_sc
1061 : integer,intent(in) :: nat_sc
1062 : integer,intent(in),optional :: prtvol
1063 : integer,intent(in),optional :: opt
1064 : !arrays
1065 : real(dp),intent(in) :: chi_org(nat_org),disv_org(nat_org),sdisv_org(nsh_org)
1066 : integer,intent(in) :: smult_org(nsh_org), smult_sc(nsh_sc)
1067 : real(dp),intent(in) :: disv_sc(nat_sc)
1068 : real(dp),intent(out) :: chi_sc(nat_sc)
1069 :
1070 : !Local variables-------------------------------
1071 : !scalars
1072 : integer :: iatom,jatom,jsh,optt
1073 : character(len=500) :: message
1074 : !arrays
1075 90 : real(dp) :: chi_orgl(nat_org)
1076 :
1077 : ! *************************************************************************
1078 :
1079 : if (present(opt)) then
1080 : optt=opt
1081 : else
1082 : optt=1
1083 : end if
1084 :
1085 :
1086 220 : do iatom=1,nat_org
1087 260 : do jsh=1,nsh_org
1088 170 : if (disv_org(iatom)==sdisv_org(jsh)) then
1089 130 : if (opt==2) then
1090 0 : chi_orgl(iatom)=chi_org(iatom)
1091 130 : else if (opt==1) then
1092 130 : chi_orgl(iatom)=chi_org(iatom)*smult_org(jsh)/smult_sc(jsh)
1093 : end if
1094 : exit
1095 : end if
1096 : end do !iatom
1097 : end do !jsh
1098 :
1099 90 : if (prtvol>1) then
1100 0 : write(message,fmt='(a,150f10.5)')' chiscwrt: chi at input ',chi_org
1101 0 : call wrtout(std_out,message,'COLL')
1102 0 : write(message,fmt='(a,150f10.5)')' chiscwrt: chi after division ',chi_orgl
1103 0 : call wrtout(std_out,message,'COLL')
1104 : end if
1105 :
1106 8970 : do iatom=1,nat_sc
1107 21880 : do jatom=1,nat_org
1108 21790 : if (disv_org(jatom)==disv_sc(iatom)) then
1109 410 : chi_sc(iatom)=chi_orgl(jatom)
1110 410 : exit
1111 12910 : else if (jatom==nat_org) then
1112 8470 : chi_sc(iatom)=0_dp
1113 : end if
1114 : end do
1115 : end do
1116 :
1117 90 : if (prtvol>1) then
1118 0 : write(message,'(a)')' chiscwrt, chi_sc '
1119 0 : call wrtout(std_out,message,'COLL')
1120 0 : call prmat(chi_sc,1,nat_sc,1,std_out)
1121 : end if
1122 :
1123 90 : end subroutine chiscwrt
1124 : !!***
1125 :
1126 : !----------------------------------------------------------------------
1127 :
1128 : !!****f* m_paw_uj/linvmat
1129 : !! NAME
1130 : !! linvmat
1131 : !!
1132 : !! FUNCTION
1133 : !! inverts real matrix inmat
1134 : !!
1135 : !! INPUTS
1136 : !! inmat(1:nat,1:nat)=matrix to be inverted
1137 : !! nat=dimension of inmat
1138 : !! nam=comment specifiying the input matrix (to be printed in output)
1139 : !! option=how to invert inmat
1140 : !! option=1 or 3 add charge bath to matrix and add gam for inversion
1141 : !! option=2 simply invert matrix
1142 : !! gam=gamma added to inmat before inversion in case charge bath is used (allows inversion of otherwise
1143 : !! singular matrix)
1144 : !! prtvol=controls output to files (see subroutine lprtmat)
1145 : !!
1146 : !! OUTPUT
1147 : !! oumat(nnat,nnat)=inverse of inmat, nnat=nat+1 for option=1 or option=3; nnat=nat for option=2
1148 : !!
1149 : !! SOURCE
1150 :
1151 266 : subroutine linvmat(inmat,oumat,nat,nam,option,gam,prtvol)
1152 :
1153 : !Arguments -------------------------------
1154 :
1155 : integer,intent(in) :: nat
1156 : real(dp),intent(in) :: gam,inmat(nat,nat)
1157 : real(dp),intent(inout) :: oumat(:,:) ! nat+1,nat+1 for option=1 or 2
1158 : ! nat,nat for option=2
1159 : character(len=500),intent(in) :: nam
1160 : integer,intent(in),optional :: prtvol,option
1161 :
1162 : !Local variables -------------------------
1163 : character(len=500) :: message
1164 : character(len=500) :: bastrin,gastrin
1165 : integer :: info,nnat,optionn !,ii,jj
1166 266 : integer,allocatable :: ipvt(:)
1167 266 : real(dp),allocatable :: hma(:,:),work(:)
1168 :
1169 : ! *********************************************************************
1170 :
1171 : if (present(option)) then
1172 : optionn=option
1173 : else
1174 : optionn=1
1175 : end if
1176 :
1177 266 : if (option==1.or.option==3) then
1178 110 : write(bastrin,'(a)')'+ charge bath '
1179 110 : write(gastrin,'(a,d10.2,a)')'+ gamma (=',gam,') '
1180 : else
1181 156 : write(bastrin,'(a)')''
1182 156 : write(gastrin,'(a)')''
1183 : end if
1184 :
1185 266 : write(message,fmt='(a)')' matrix '//trim(nam)
1186 266 : call lprtmat(message,1,prtvol,inmat,nat)
1187 :
1188 266 : if (option==1.or.option==3) then
1189 110 : call blow_pawuj(inmat,nat,oumat)
1190 110 : write(message,fmt='(a,a)')' ',trim(nam)//trim(bastrin)
1191 110 : call lprtmat(message,1,prtvol,oumat,nat+1)
1192 1519370 : oumat=oumat+gam
1193 110 : nnat=nat+1
1194 : else
1195 156 : nnat=nat
1196 2028 : oumat=inmat
1197 156 : oumat(1,1)=inmat(1,1)
1198 : end if
1199 :
1200 :
1201 1064 : ABI_MALLOC(hma,(nnat,nnat))
1202 798 : ABI_MALLOC(work,(nnat))
1203 798 : ABI_MALLOC(ipvt,(nnat))
1204 9754 : work=0_dp
1205 1521398 : hma(:,:)=oumat
1206 :
1207 266 : call dgetrf(nnat,nnat,hma,nnat,ipvt,info)
1208 266 : if (.not.info==0) then
1209 0 : write(message, '(3a)' ) 'Matrix '//trim(nam)//' is singular',ch10,'Probably too many symmetries kept'
1210 0 : call wrtout(ab_out,message,'COLL')
1211 0 : return
1212 : end if
1213 :
1214 266 : call dgetri(nnat,hma,nnat,ipvt,work,nnat,info)
1215 1521398 : oumat=hma(:,:)
1216 :
1217 266 : write(message,fmt='(2a,a)')' ('//trim(nam)//trim(bastrin)//trim(gastrin)//')^(-1)'
1218 266 : call lprtmat(message,1,prtvol,oumat,nnat)
1219 :
1220 266 : ABI_FREE(hma)
1221 266 : ABI_FREE(work)
1222 266 : ABI_FREE(ipvt)
1223 :
1224 0 : end subroutine linvmat
1225 : !!***
1226 :
1227 : !----------------------------------------------------------------------
1228 :
1229 : !!****f* m_paw_uj/lprtmat
1230 : !! NAME
1231 : !! lprtmat
1232 : !!
1233 : !! FUNCTION
1234 : !! prints out the real matrix mmat
1235 : !!
1236 : !! INPUTS
1237 : !! mmat(nat,nat)=matrix to be printed
1238 : !! nat=dimension of mmat
1239 : !! prtvol specifies the volume of printing
1240 : !! 3: print the whole matrix
1241 : !! 2: print the first line
1242 : !! 1: do not print anything
1243 : !! chan specifies the output files
1244 : !! 1: output only to std_out
1245 : !! 2: output also to ab_out
1246 : !! commnt=comment specifying matirix
1247 : !!
1248 : !! OUTPUT
1249 : !! oumat(nat+1,nat+1)=inverse of inmat
1250 : !!
1251 : !! SOURCE
1252 :
1253 697 : subroutine lprtmat(commnt,chan,prtvol,mmat,nat)
1254 :
1255 : !Arguments -------------------------------
1256 : integer,intent(in) :: nat,chan,prtvol
1257 : real(dp),intent(in) :: mmat(nat,nat)
1258 : character(len=500),intent(in) :: commnt
1259 :
1260 : !Local variables -------------------------
1261 : character(len=500) :: message
1262 : ! *********************************************************************
1263 :
1264 697 : if (prtvol==3) then
1265 312 : write(message,fmt='(a)') trim(commnt)
1266 312 : call wrtout(std_out,message,'COLL')
1267 312 : call prmat(mmat,nat,nat,nat,std_out)
1268 312 : if (chan==2) then
1269 0 : call wrtout(ab_out,message,'COLL')
1270 0 : call prmat(mmat,nat,nat,nat,ab_out)
1271 : end if
1272 312 : write(message,*)ch10
1273 312 : call wrtout(std_out,message,'COLL')
1274 312 : if (chan==2) then
1275 0 : call wrtout(ab_out,message,'COLL')
1276 : end if
1277 : end if
1278 :
1279 697 : if (prtvol==2) then
1280 0 : write(message,fmt='(a)') trim(commnt)
1281 0 : call wrtout(std_out,message,'COLL')
1282 0 : call prmat(mmat,1,nat,nat,std_out)
1283 0 : if (chan==2) then
1284 0 : call wrtout(ab_out,message,'COLL')
1285 0 : call prmat(mmat,1,nat,nat,ab_out)
1286 : end if
1287 0 : write(message,*)ch10
1288 0 : call wrtout(std_out,message,'COLL')
1289 0 : if (chan==2) then
1290 0 : call wrtout(ab_out,message,'COLL')
1291 : end if
1292 : end if
1293 :
1294 697 : end subroutine lprtmat
1295 : !!***
1296 :
1297 : !----------------------------------------------------------------------
1298 :
1299 : !!****f* m_paw_uj/lcalcu
1300 : !! NAME
1301 : !! lcalcu
1302 : !!
1303 : !! FUNCTION
1304 : !! prints out real the real matrice mmat
1305 : !!
1306 : !! INPUTS
1307 : !! magv=magnetic ordering of the ions (-1 of down/1 for up)
1308 : !! natom=number of atoms
1309 : !! rprimd(3,3)=lattic vectors of unit cell
1310 : !! xred(3,natom)=positions of atoms
1311 : !! chi(natom)=full response of atoms due to shift on atom pawujat
1312 : !! chi0(natom)= response of atoms due to shift on atom pawujat
1313 : !! pawujat=specifies on which atom the potential shift was done
1314 : !! prtvol=controls output to files (see subroutine lprtmat)
1315 : !! gam=gamma to be used for inversion of matrices (see subroutine livmat)
1316 : !! opt=wether to use charge bath (1 or 3) or not (else)
1317 : !!
1318 : !! OUTPUT
1319 : !! ures=resulting U (in eV) on atom pawujat
1320 : !!
1321 : !! SOURCE
1322 :
1323 55 : subroutine lcalcu(magv,natom,rprimd,xred,chi,chi0,pawujat,ures,prtvol,gam,opt)
1324 :
1325 : !Arguments ------------------------------------
1326 : !scalars
1327 : integer,intent(in) :: natom
1328 : integer,intent(in),optional :: opt,pawujat,prtvol
1329 : real(dp),intent(in),optional:: gam
1330 : real(dp),intent(out) :: ures
1331 : !arrays
1332 : integer,intent(in) :: magv(natom)
1333 : real(dp),intent(in) :: rprimd(3,3),xred(3,natom),chi(natom),chi0(natom)
1334 :
1335 : !Local variables-------------------------------
1336 : !scalars
1337 : character(len=500) :: message
1338 : integer :: optt,prtvoll,nnatom
1339 : real(dp) :: gamm
1340 : !arrays
1341 55 : real(dp),allocatable :: chi0matrix1(:,:),chimatrix2(:,:),auginvchi0matrix3(:,:)
1342 55 : real(dp),allocatable :: auginvchimatrix4(:,:),uresmatrix(:,:)
1343 :
1344 : ! *********************************************************************
1345 :
1346 55 : if (present(opt)) then
1347 55 : optt=opt
1348 : else
1349 0 : optt=1
1350 : end if
1351 :
1352 55 : if (present(prtvol)) then
1353 55 : prtvoll=prtvol
1354 : else
1355 0 : prtvoll=1
1356 : end if
1357 :
1358 55 : if (present(gam)) then
1359 55 : gamm=gam
1360 : else
1361 0 : gamm=1_dp
1362 : end if
1363 :
1364 55 : if (optt==1.or.optt==3) then
1365 55 : nnatom=natom+1
1366 : else
1367 0 : nnatom=natom
1368 : end if
1369 :
1370 220 : ABI_MALLOC(chi0matrix1,(natom,natom))
1371 165 : ABI_MALLOC(chimatrix2,(natom,natom))
1372 220 : ABI_MALLOC(auginvchi0matrix3,(nnatom,nnatom))
1373 165 : ABI_MALLOC(auginvchimatrix4,(nnatom,nnatom))
1374 165 : ABI_MALLOC(uresmatrix,(nnatom,nnatom))
1375 :
1376 55 : call ioniondist(natom,rprimd,xred,chi0matrix1,3,chi0,magv,pawujat,prtvoll)
1377 55 : call ioniondist(natom,rprimd,xred,chimatrix2,3,chi,magv,pawujat,prtvoll)
1378 :
1379 55 : write(message,fmt='(a)')'response chi_0'
1380 55 : call linvmat(chi0matrix1,auginvchi0matrix3,natom,message,optt,gamm,prtvoll)
1381 55 : call wrtout(std_out,message,'COLL')
1382 :
1383 55 : write(message,fmt='(a)')'response chi'
1384 55 : call linvmat(chimatrix2,auginvchimatrix4,natom,message,optt,gamm,prtvoll)
1385 55 : call wrtout(std_out,message,'COLL')
1386 :
1387 759740 : uresmatrix=(auginvchi0matrix3-auginvchimatrix4)*Ha_eV
1388 :
1389 55 : write(message,fmt='(a,i3,a)')' (chi_0)^(-1)-(chi)^(-1) (eV)'
1390 55 : call lprtmat(message,2,prtvoll,uresmatrix,nnatom)
1391 55 : call wrtout(std_out,message,'COLL')
1392 :
1393 55 : ures=uresmatrix(1,pawujat)
1394 :
1395 55 : ABI_FREE(chi0matrix1)
1396 55 : ABI_FREE(chimatrix2)
1397 55 : ABI_FREE(auginvchi0matrix3)
1398 55 : ABI_FREE(auginvchimatrix4)
1399 55 : ABI_FREE(uresmatrix)
1400 :
1401 :
1402 55 : end subroutine lcalcu
1403 : !!***
1404 :
1405 : !----------------------------------------------------------------------
1406 :
1407 : !!****f* m_paw_uj/blow_pawuj
1408 : !!
1409 : !! NAME
1410 : !! blow_pawuj
1411 : !!
1412 : !! FUNCTION
1413 : !! This subroutine reads a real nxn matrice and appends lines n+1 and clumn n+1 containing
1414 : !! the sum of the lines
1415 : !!
1416 : !! INPUTS
1417 : !! mat(nj,nj) matrix to be completed
1418 : !!
1419 : !! OUTPUT
1420 : !! matt(nj+1,nj+1) completed matrix
1421 : !!
1422 : !! SOURCE
1423 :
1424 110 : subroutine blow_pawuj(mat,nj,matt)
1425 :
1426 : !Arguments ------------------------------------
1427 : !scalars
1428 : integer,intent(in) :: nj
1429 : !arrays
1430 : real(dp),intent(in) :: mat(nj,nj)
1431 : real(dp),intent(out) :: matt(nj+1,nj+1)
1432 :
1433 : !Local variables-------------------------------
1434 : !scalars
1435 : integer :: ii
1436 : !arrays
1437 :
1438 : ! *************************************************************************
1439 :
1440 1501330 : matt(1:nj,1:nj)=mat
1441 9020 : do ii = 1,nj
1442 1501330 : matt(ii,nj+1)=-sum(matt(ii,1:nj))
1443 : end do
1444 :
1445 9130 : do ii = 1,nj+1
1446 1510350 : matt(nj+1,ii)=-sum(matt(1:nj,ii))
1447 : end do
1448 :
1449 110 : end subroutine blow_pawuj
1450 : !!***
1451 :
1452 : !----------------------------------------------------------------------
1453 :
1454 0 : END MODULE m_paw_uj
1455 : !!***
|