Branch data 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 [ + + + + : 630 : 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 : : !!***
|