TABLE OF CONTENTS
- ABINIT/dfpt_ciflexoout
- ABINIT/dfpt_ddmdqout
- ABINIT/dfpt_flexo
- ABINIT/dfpt_isdqout
- ABINIT/dfpt_qdrpole
- ABINIT/dfpt_qdrpout
- ABINIT/m_dfpt_lw
ABINIT/dfpt_ciflexoout [ Functions ]
NAME
dfpt_ciflexoout
FUNCTION
This subroutine gathers the different terms entering the electrocic flexoelectric tensor, perfofms the transformation from reduced to cartesian coordinates and writes out the tensor in output files.
INPUTS
elqgradhart(2,3,3,3,3)=electronic electrostatic contribution from the q-gradient of the Hartree potential elflexoflg(3,3,3,3)=array that indicates which elements of the electronic contribution to the flexoelectric tensor have been calculated elflexowf(2,3,3,3,3)=total wave function contributions to the electronic flexoelectric tensor (except t4) elflexowf_t1(2,3,3,3,3)=term 1 of the wave function contribution elflexowf_t2(2,3,3,3,3)=term 2 of the wave function contribution elflexowf_t3(2,3,3,3,3)=term 3 of the wave function contribution elflexowf_t4(2,3,3,3,3)=term 4 of the wave function contribution (type-I) elflexowf_t5(2,3,3,3,3)=term 5 of the wave function contribution gprimd(3,3)=reciprocal space dimensional primitive translations kptopt=2 time reversal symmetry is enforced, 3 trs is not enforced (for debugging purposes) matom=number of atoms mpert=maximum number of perturbations nefipert=number of electric field perturbations nstrpert=number of strain perturbations nq1grad=number of q1 (q_{\gamma}) gradients pert_efield(3,nefipert)=array with the info for the electric field perturbations pert_strain(6,nstrpert)=array with the info for the strain perturbations prtvol=volume of information to be printed. 1-> The different contributions to the quadrupole are printed. q1grad(3,nq1grad)=array with the info for the q1 (q_{\gamma}) gradients rprimd(3,3)=dimensional primitive translations in real space (bohr) ucvol=unit cell volume in bohr**3.
OUTPUT
d3etot(2,3,mpert,3,mpert,3,mpert)= matrix of the 3DTE
SIDE EFFECTS
NOTES
SOURCE
3131 subroutine dfpt_ciflexoout(d3etot,elflexoflg,elflexowf,elflexowf_t1,elflexowf_t2, & 3132 & elflexowf_t3,elflexowf_t4,elflexowf_t5, & 3133 & elqgradhart,gprimd,kptopt,matom,mpert,nefipert,& 3134 & nstrpert,nq1grad,pert_efield,pert_strain,prtvol,q1grad,rprimd,ucvol) 3135 3136 !Arguments ------------------------------------ 3137 !scalars 3138 integer,intent(in) :: kptopt,matom,mpert,nefipert,nstrpert,nq1grad,prtvol 3139 real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert) 3140 real(dp),intent(in) :: ucvol 3141 3142 !arrays 3143 integer,intent(in) :: elflexoflg(3,3,3,3) 3144 integer,intent(in) :: pert_efield(3,nefipert) 3145 integer,intent(in) :: pert_strain(6,nstrpert) 3146 integer,intent(in) :: q1grad(3,nq1grad) 3147 real(dp),intent(in) :: elflexowf(2,3,3,3,3) 3148 real(dp),intent(inout) :: elflexowf_t1(2,3,3,3,3) 3149 real(dp),intent(inout) :: elflexowf_t2(2,3,3,3,3) 3150 real(dp),intent(inout) :: elflexowf_t3(2,3,3,3,3) 3151 real(dp),intent(inout) :: elflexowf_t4(2,3,3,3,3) 3152 real(dp),intent(inout) :: elflexowf_t5(2,3,3,3,3) 3153 real(dp),intent(inout) :: elqgradhart(2,3,3,3,3) 3154 real(dp),intent(in) :: gprimd(3,3) 3155 real(dp),intent(in) :: rprimd(3,3) 3156 3157 !Local variables------------------------------- 3158 !scalars 3159 integer :: alpha,beta,delta,efipert,gamma 3160 integer :: ibuf,iefidir,iefipert,ii,iq1dir,iq1grad,istr1dir,istr2dir,istrpert 3161 integer :: q1pert,strcomp,strpert 3162 integer, parameter :: re=1,im=2 3163 real(dp) :: fac,tmpim,tmpre,ucvolinv 3164 character(len=500) :: msg 3165 3166 !arrays 3167 integer,allocatable :: cartflg_t4(:,:,:,:),redflg(:,:,:,:) 3168 integer :: flg1(3),flg2(3) 3169 real(dp) :: vec1(3),vec2(3) 3170 real(dp),allocatable :: elec_flexotens_cart(:,:,:,:,:),elec_flexotens_red(:,:,:,:,:) 3171 real(dp),allocatable :: elflexowf_buffer_cart(:,:,:,:,:,:),elflexowf_t4_cart(:,:,:,:,:) 3172 3173 ! ************************************************************************* 3174 3175 DBG_ENTER("COLL") 3176 3177 !Gather the different terms in the electronic contribution to the flexoelectric tensor 3178 ABI_MALLOC(elec_flexotens_red,(2,3,3,3,3)) 3179 ! elec_flexotens_red=zero 3180 ucvolinv= 1.0_dp/ucvol 3181 3182 if (kptopt==3) then 3183 3184 !Compute real and 'true' imaginary parts of flexoelectric tensor and independent terms 3185 !T4 term needs further treatment and it will be lately added to the cartesian coordinates 3186 !version of the flexoelectric tensor 3187 do istrpert=1,nstrpert 3188 istr1dir=pert_strain(3,istrpert) 3189 istr2dir=pert_strain(4,istrpert) 3190 do iq1grad=1,nq1grad 3191 iq1dir=q1grad(2,iq1grad) 3192 do iefipert=1,nefipert 3193 iefidir=pert_efield(2,iefipert) 3194 3195 if (elflexoflg(iefidir,iq1dir,istr1dir,istr2dir)==1) then 3196 3197 elec_flexotens_red(re,iefidir,iq1dir,istr1dir,istr2dir)=2.0_dp*ucvolinv* & 3198 & ( elqgradhart(re,iefidir,iq1dir,istr1dir,istr2dir) + & 3199 & elflexowf(re,iefidir,iq1dir,istr1dir,istr2dir) ) 3200 elec_flexotens_red(im,iefidir,iq1dir,istr1dir,istr2dir)=2.0_dp*ucvolinv* & 3201 & ( elqgradhart(im,iefidir,iq1dir,istr1dir,istr2dir) + & 3202 & elflexowf(im,iefidir,iq1dir,istr1dir,istr2dir) ) 3203 3204 !Multiply by the imaginary unit that has been factorized out 3205 tmpre=elec_flexotens_red(re,iefidir,iq1dir,istr1dir,istr2dir) 3206 tmpim=elec_flexotens_red(im,iefidir,iq1dir,istr1dir,istr2dir) 3207 elec_flexotens_red(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim 3208 elec_flexotens_red(im,iefidir,iq1dir,istr1dir,istr2dir)=tmpre 3209 3210 !Divide by the imaginary unit the T4 term 3211 !(this is because a -i factor has been factorized out in all the individual contributions to this therm) 3212 tmpre=elflexowf_t4(re,iefidir,istr1dir,istr2dir,iq1dir) 3213 tmpim=elflexowf_t4(im,iefidir,istr1dir,istr2dir,iq1dir) 3214 elflexowf_t4(re,iefidir,istr1dir,istr2dir,iq1dir)=tmpim*2.0_dp*ucvolinv 3215 elflexowf_t4(im,iefidir,istr1dir,istr2dir,iq1dir)=-tmpre*2.0_dp*ucvolinv 3216 3217 !Compute and save individual terms in mixed coordinates 3218 if (prtvol>=10) then 3219 3220 tmpre=elqgradhart(re,iefidir,iq1dir,istr1dir,istr2dir) 3221 tmpim=elqgradhart(im,iefidir,iq1dir,istr1dir,istr2dir) 3222 elqgradhart(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3223 elqgradhart(im,iefidir,iq1dir,istr1dir,istr2dir)=tmpre*2.0_dp*ucvolinv 3224 3225 tmpre=elflexowf_t1(re,iefidir,iq1dir,istr1dir,istr2dir) 3226 tmpim=elflexowf_t1(im,iefidir,iq1dir,istr1dir,istr2dir) 3227 elflexowf_t1(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3228 elflexowf_t1(im,iefidir,iq1dir,istr1dir,istr2dir)=tmpre*2.0_dp*ucvolinv 3229 3230 tmpre=elflexowf_t2(re,iefidir,iq1dir,istr1dir,istr2dir) 3231 tmpim=elflexowf_t2(im,iefidir,iq1dir,istr1dir,istr2dir) 3232 elflexowf_t2(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3233 elflexowf_t2(im,iefidir,iq1dir,istr1dir,istr2dir)=tmpre*2.0_dp*ucvolinv 3234 3235 tmpre=elflexowf_t3(re,iefidir,iq1dir,istr1dir,istr2dir) 3236 tmpim=elflexowf_t3(im,iefidir,iq1dir,istr1dir,istr2dir) 3237 elflexowf_t3(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3238 elflexowf_t3(im,iefidir,iq1dir,istr1dir,istr2dir)=tmpre*2.0_dp*ucvolinv 3239 3240 tmpre=elflexowf_t5(re,iefidir,iq1dir,istr1dir,istr2dir) 3241 tmpim=elflexowf_t5(im,iefidir,iq1dir,istr1dir,istr2dir) 3242 elflexowf_t5(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3243 elflexowf_t5(im,iefidir,iq1dir,istr1dir,istr2dir)=tmpre*2.0_dp*ucvolinv 3244 3245 end if 3246 3247 end if 3248 3249 end do 3250 end do 3251 end do 3252 3253 else if (kptopt==2) then 3254 3255 !Compute real part of flexoelectric tensor and independent terms 3256 !T4 term needs further treatment and it will be lately added to the cartesian coordinates 3257 !version of the flexoelectric tensor 3258 do istrpert=1,nstrpert 3259 istr1dir=pert_strain(3,istrpert) 3260 istr2dir=pert_strain(4,istrpert) 3261 do iq1grad=1,nq1grad 3262 iq1dir=q1grad(2,iq1grad) 3263 do iefipert=1,nefipert 3264 iefidir=pert_efield(2,iefipert) 3265 3266 if (elflexoflg(iefidir,iq1dir,istr1dir,istr2dir)==1) then 3267 3268 elec_flexotens_red(re,iefidir,iq1dir,istr1dir,istr2dir)=2.0_dp*ucvolinv* & 3269 & ( elqgradhart(re,iefidir,iq1dir,istr1dir,istr2dir) + & 3270 & elflexowf(re,iefidir,iq1dir,istr1dir,istr2dir) ) 3271 elec_flexotens_red(im,iefidir,iq1dir,istr1dir,istr2dir)=2.0_dp*ucvolinv* & 3272 & ( elqgradhart(im,iefidir,iq1dir,istr1dir,istr2dir) + & 3273 & elflexowf(im,iefidir,iq1dir,istr1dir,istr2dir) ) 3274 3275 !Multiply by the imaginary unit that has been factorized out 3276 tmpim=elec_flexotens_red(im,iefidir,iq1dir,istr1dir,istr2dir) 3277 elec_flexotens_red(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim 3278 elec_flexotens_red(im,iefidir,iq1dir,istr1dir,istr2dir)=0.0_dp 3279 3280 !Divide by the imaginary unit the T4 term 3281 !(this is because a -i factor has been factorized out in all the individual contributions to this therm) 3282 tmpim=elflexowf_t4(im,iefidir,istr1dir,istr2dir,iq1dir) 3283 elflexowf_t4(re,iefidir,istr1dir,istr2dir,iq1dir)=2.0_dp*tmpim*ucvolinv 3284 elflexowf_t4(im,iefidir,istr1dir,istr2dir,iq1dir)=0.0_dp 3285 3286 !Compute and save individual terms in mixed coordinates 3287 if (prtvol>=10) then 3288 3289 tmpim=elqgradhart(im,iefidir,iq1dir,istr1dir,istr2dir) 3290 elqgradhart(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3291 elqgradhart(im,iefidir,iq1dir,istr1dir,istr2dir)=0.0_dp 3292 3293 tmpim=elflexowf_t1(im,iefidir,iq1dir,istr1dir,istr2dir) 3294 elflexowf_t1(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3295 elflexowf_t1(im,iefidir,iq1dir,istr1dir,istr2dir)=0.0_dp 3296 3297 tmpim=elflexowf_t2(im,iefidir,iq1dir,istr1dir,istr2dir) 3298 elflexowf_t2(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3299 elflexowf_t2(im,iefidir,iq1dir,istr1dir,istr2dir)=0.0_dp 3300 3301 tmpim=elflexowf_t3(im,iefidir,iq1dir,istr1dir,istr2dir) 3302 elflexowf_t3(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3303 elflexowf_t3(im,iefidir,iq1dir,istr1dir,istr2dir)=0.0_dp 3304 3305 tmpim=elflexowf_t5(im,iefidir,iq1dir,istr1dir,istr2dir) 3306 elflexowf_t5(re,iefidir,iq1dir,istr1dir,istr2dir)=-tmpim*2.0_dp*ucvolinv 3307 elflexowf_t5(im,iefidir,iq1dir,istr1dir,istr2dir)=0.0_dp 3308 3309 end if 3310 3311 end if 3312 3313 end do 3314 end do 3315 end do 3316 3317 else 3318 write(msg,"(1a)") 'kptopt must be 2 or 3 for long-wave DFPT calculations' 3319 ABI_BUG(msg) 3320 end if 3321 3322 !Transormation to complete cartesian coordinates the flexoelectric tensor 3323 !and separately the T4 term 3324 ABI_MALLOC(elec_flexotens_cart,(2,3,3,3,3)) 3325 ABI_MALLOC(elflexowf_t4_cart,(2,3,3,3,3)) 3326 ABI_MALLOC(cartflg_t4,(3,3,3,3)) 3327 elec_flexotens_cart=elec_flexotens_red 3328 elflexowf_t4_cart=elflexowf_t4 3329 cartflg_t4=0 3330 3331 ! ABI_FREE(elec_flexotens_red) 3332 3333 if (prtvol>=10) then 3334 ABI_MALLOC(elflexowf_buffer_cart,(5,2,3,3,3,3)) 3335 elflexowf_buffer_cart(1,:,:,:,:,:)=elflexowf_t1(:,:,:,:,:) 3336 elflexowf_buffer_cart(2,:,:,:,:,:)=elflexowf_t2(:,:,:,:,:) 3337 elflexowf_buffer_cart(3,:,:,:,:,:)=elflexowf_t3(:,:,:,:,:) 3338 elflexowf_buffer_cart(4,:,:,:,:,:)=elqgradhart(:,:,:,:,:) 3339 elflexowf_buffer_cart(5,:,:,:,:,:)=elflexowf_t5(:,:,:,:,:) 3340 end if 3341 3342 !1st transform coordinates of the electric field derivative of the flexoelectric tensor 3343 do istr2dir=1,3 3344 do istr1dir=1,3 3345 do iq1dir=1,3 3346 do ii=1,2 3347 do iefidir=1,3 3348 vec1(iefidir)=elec_flexotens_cart(ii,iefidir,iq1dir,istr1dir,istr2dir) 3349 flg1(iefidir)=elflexoflg(iefidir,iq1dir,istr1dir,istr2dir) 3350 end do 3351 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 3352 do iefidir=1,3 3353 elec_flexotens_cart(ii,iefidir,iq1dir,istr1dir,istr2dir)=vec2(iefidir) 3354 end do 3355 end do 3356 end do 3357 end do 3358 end do 3359 3360 !Do now the transformation of the electric field derivative for the T4 term 3361 do istr2dir=1,3 3362 do istr1dir=1,3 3363 do iq1dir=1,3 3364 do ii=1,2 3365 do iefidir=1,3 3366 vec1(iefidir)=elflexowf_t4_cart(ii,iefidir,istr1dir,istr2dir,iq1dir) 3367 flg1(iefidir)=elflexoflg(iefidir,iq1dir,istr1dir,istr2dir) 3368 end do 3369 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 3370 do iefidir=1,3 3371 elflexowf_t4_cart(ii,iefidir,istr1dir,istr2dir,iq1dir)=vec2(iefidir) 3372 cartflg_t4(iefidir,istr1dir,istr2dir,iq1dir)=flg2(iefidir) 3373 end do 3374 end do 3375 end do 3376 end do 3377 end do 3378 3379 !Do now the transformation of the electric field derivative for the other therms 3380 if (prtvol>=10) then 3381 do ibuf=1,5 3382 do istr2dir=1,3 3383 do istr1dir=1,3 3384 do iq1dir=1,3 3385 do ii=1,2 3386 do iefidir=1,3 3387 vec1(iefidir)=elflexowf_buffer_cart(ibuf,ii,iefidir,iq1dir,istr1dir,istr2dir) 3388 flg1(iefidir)=elflexoflg(iefidir,iq1dir,istr1dir,istr2dir) 3389 end do 3390 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 3391 do iefidir=1,3 3392 elflexowf_buffer_cart(ibuf,ii,iefidir,iq1dir,istr1dir,istr2dir)=vec2(iefidir) 3393 end do 3394 end do 3395 end do 3396 end do 3397 end do 3398 end do 3399 end if 3400 3401 !2nd transform coordinates of the q-gradient (treat it as electric field) 3402 !of the flexoelectric tensor 3403 do istr2dir=1,3 3404 do istr1dir=1,3 3405 do iefidir=1,3 3406 do ii=1,2 3407 do iq1dir=1,3 3408 vec1(iq1dir)=elec_flexotens_cart(ii,iefidir,iq1dir,istr1dir,istr2dir) 3409 flg1(iq1dir)=elflexoflg(iefidir,iq1dir,istr1dir,istr2dir) 3410 end do 3411 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 3412 do iq1dir=1,3 3413 elec_flexotens_cart(ii,iefidir,iq1dir,istr1dir,istr2dir)=vec2(iq1dir) 3414 end do 3415 end do 3416 end do 3417 end do 3418 end do 3419 3420 !2nd transform coordinates of the q-gradient (treat it as electric field) 3421 !of the individual terms 3422 if (prtvol>=10) then 3423 do ibuf=1,5 3424 do istr2dir=1,3 3425 do istr1dir=1,3 3426 do iefidir=1,3 3427 do ii=1,2 3428 do iq1dir=1,3 3429 vec1(iq1dir)=elflexowf_buffer_cart(ibuf,ii,iefidir,iq1dir,istr1dir,istr2dir) 3430 flg1(iq1dir)=elflexoflg(iefidir,iq1dir,istr1dir,istr2dir) 3431 end do 3432 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 3433 do iq1dir=1,3 3434 elflexowf_buffer_cart(ibuf,ii,iefidir,iq1dir,istr1dir,istr2dir)=vec2(iq1dir) 3435 end do 3436 end do 3437 end do 3438 end do 3439 end do 3440 end do 3441 end if 3442 3443 !Write the flexoelectric tensor in cartesian coordinates 3444 !Open output files 3445 if (prtvol>=10) then 3446 open(unit=71,file='elec_flexo_wf_t1.out',status='unknown',form='formatted',action='write') 3447 open(unit=72,file='elec_flexo_wf_t2.out',status='unknown',form='formatted',action='write') 3448 open(unit=73,file='elec_flexo_wf_t3.out',status='unknown',form='formatted',action='write') 3449 open(unit=74,file='elec_flexo_wf_t4.out',status='unknown',form='formatted',action='write') 3450 open(unit=75,file='elec_flexo_wf_t5.out',status='unknown',form='formatted',action='write') 3451 open(unit=76,file='elec_flexo_elecstic.out',status='unknown',form='formatted',action='write') 3452 end if 3453 3454 write(ab_out,'(a)')' ' 3455 write(ab_out,'(a)')' Clamped-ion flexoelectric tensor, in cartesian coordinates,' 3456 write(ab_out,'(a)')' efidir qgrdir strdir1 strdir2 real part imaginary part' 3457 do istr2dir=1,3 3458 delta=istr2dir 3459 do istr1dir=1,3 3460 beta=istr1dir 3461 do iq1dir=1,3 3462 gamma=iq1dir 3463 do iefidir=1,3 3464 alpha=iefidir 3465 3466 if (cartflg_t4(alpha,beta,delta,gamma)==1 .and. cartflg_t4(alpha,delta,gamma,beta)==1 & 3467 & .and. cartflg_t4(alpha,gamma,beta,delta)==1) then 3468 3469 !Converts the T4 term to type-II form 3470 tmpre= elflexowf_t4_cart(re,alpha,beta,delta,gamma) + & 3471 & elflexowf_t4_cart(re,alpha,delta,gamma,beta) - & 3472 & elflexowf_t4_cart(re,alpha,gamma,beta,delta) 3473 3474 tmpim= elflexowf_t4_cart(im,alpha,beta,delta,gamma) + & 3475 & elflexowf_t4_cart(im,alpha,delta,gamma,beta) - & 3476 & elflexowf_t4_cart(im,alpha,gamma,beta,delta) 3477 3478 !Add the T4 term after conversion to type-II form 3479 elec_flexotens_cart(re,alpha,gamma,beta,delta)= & 3480 & elec_flexotens_cart(re,alpha,gamma,beta,delta) + tmpre 3481 elec_flexotens_cart(im,alpha,gamma,beta,delta)= & 3482 & elec_flexotens_cart(im,alpha,gamma,beta,delta) + tmpim 3483 3484 !Writes the complete flexoelectric tensor 3485 write(ab_out,'(4(i5,3x),2(1x,f20.10))') alpha,gamma,beta,delta, & 3486 & elec_flexotens_cart(re,alpha,gamma,beta,delta), & 3487 & elec_flexotens_cart(im,alpha,gamma,beta,delta) 3488 3489 if (prtvol>=10) then 3490 write(71,'(4(i5,3x),2(1x,f20.10))') alpha,gamma,beta,delta, & 3491 & elflexowf_buffer_cart(1,re,alpha,gamma,beta,delta), & 3492 & elflexowf_buffer_cart(1,im,alpha,gamma,beta,delta) 3493 3494 write(72,'(4(i5,3x),2(1x,f20.10))') alpha,gamma,beta,delta, & 3495 & elflexowf_buffer_cart(2,re,alpha,gamma,beta,delta), & 3496 & elflexowf_buffer_cart(2,im,alpha,gamma,beta,delta) 3497 3498 write(73,'(4(i5,3x),2(1x,f20.10))') alpha,gamma,beta,delta, & 3499 & elflexowf_buffer_cart(3,re,alpha,gamma,beta,delta), & 3500 & elflexowf_buffer_cart(3,im,alpha,gamma,beta,delta) 3501 3502 write(74,'(4(i5,3x),2(1x,f20.10))') alpha,gamma,beta,delta, & 3503 & tmpre, tmpim 3504 3505 write(75,'(4(i5,3x),2(1x,f20.10))') alpha,gamma,beta,delta, & 3506 & elflexowf_buffer_cart(5,re,alpha,gamma,beta,delta), & 3507 & elflexowf_buffer_cart(5,im,alpha,gamma,beta,delta) 3508 3509 write(76,'(4(i5,3x),2(1x,f20.10))') alpha,gamma,beta,delta, & 3510 & elflexowf_buffer_cart(4,re,alpha,gamma,beta,delta), & 3511 & elflexowf_buffer_cart(4,im,alpha,gamma,beta,delta) 3512 end if 3513 3514 end if 3515 3516 end do 3517 end do 3518 write(ab_out,'(a)')' ' 3519 if (prtvol>=10) then 3520 write(71,*)' ' 3521 write(72,*)' ' 3522 write(73,*)' ' 3523 write(74,*)' ' 3524 write(75,*)' ' 3525 write(76,*)' ' 3526 end if 3527 end do 3528 end do 3529 3530 if (prtvol>=10) then 3531 close(71) 3532 close(72) 3533 close(73) 3534 close(74) 3535 close(75) 3536 close(76) 3537 ABI_FREE(elflexowf_buffer_cart) 3538 end if 3539 3540 !Calculate the contribution to the d3etot in mixed (reduced/cartesian) coordinates 3541 elec_flexotens_red=elec_flexotens_cart 3542 ABI_FREE(elec_flexotens_cart) 3543 ABI_FREE(elflexowf_t4_cart) 3544 ABI_FREE(cartflg_t4) 3545 ABI_MALLOC(redflg,(3,3,3,3)) 3546 redflg=0 3547 3548 !1st transform back coordinates of the electric field derivative of the flexoelectric tensor 3549 fac=two_pi ** 2 3550 do istr2dir=1,3 3551 do istr1dir=1,3 3552 do iq1dir=1,3 3553 do ii=1,2 3554 do iefidir=1,3 3555 vec1(iefidir)=elec_flexotens_red(ii,iefidir,iq1dir,istr1dir,istr2dir) 3556 flg1(iefidir)=elflexoflg(iefidir,iq1dir,istr1dir,istr2dir) 3557 end do 3558 call cart39(flg1,flg2,transpose(rprimd),matom+2,matom,transpose(gprimd),vec1,vec2) 3559 do iefidir=1,3 3560 elec_flexotens_red(ii,iefidir,iq1dir,istr1dir,istr2dir)=vec2(iefidir)*fac 3561 redflg(iefidir,iq1dir,istr1dir,istr2dir)=flg2(iefidir) 3562 end do 3563 end do 3564 end do 3565 end do 3566 end do 3567 3568 !2nd transform back coordinates of the q-gradient (treat it as electric field) 3569 !of the flexoelectric tensor 3570 do istr2dir=1,3 3571 do istr1dir=1,3 3572 do iefidir=1,3 3573 do ii=1,2 3574 do iq1dir=1,3 3575 vec1(iq1dir)=elec_flexotens_red(ii,iefidir,iq1dir,istr1dir,istr2dir) 3576 flg1(iq1dir)=elflexoflg(iefidir,iq1dir,istr1dir,istr2dir) 3577 end do 3578 call cart39(flg1,flg2,transpose(rprimd),matom+2,matom,transpose(gprimd),vec1,vec2) 3579 do iq1dir=1,3 3580 elec_flexotens_red(ii,iefidir,iq1dir,istr1dir,istr2dir)=vec2(iq1dir)*fac 3581 end do 3582 end do 3583 end do 3584 end do 3585 end do 3586 3587 !Add contributions to d3etot 3588 efipert=matom+2 3589 q1pert=matom+8 3590 fac=ucvol/two 3591 do istrpert=1,nstrpert 3592 strpert=pert_strain(1,istrpert) 3593 strcomp=pert_strain(2,istrpert) 3594 istr1dir=pert_strain(3,istrpert) 3595 istr2dir=pert_strain(4,istrpert) 3596 do iq1grad=1,nq1grad 3597 iq1dir=q1grad(2,iq1grad) 3598 do iefipert=1,nefipert 3599 iefidir=pert_efield(2,iefipert) 3600 3601 if (redflg(iefidir,iq1dir,istr1dir,istr2dir)==1) then 3602 d3etot(re,iefidir,efipert,strcomp,strpert,iq1dir,q1pert)= & 3603 & elec_flexotens_red(im,iefidir,iq1dir,istr1dir,istr2dir)*fac 3604 d3etot(im,iefidir,efipert,strcomp,strpert,iq1dir,q1pert)= & 3605 & -elec_flexotens_red(re,iefidir,iq1dir,istr1dir,istr2dir)*fac 3606 end if 3607 3608 end do 3609 end do 3610 end do 3611 3612 ABI_FREE(elec_flexotens_red) 3613 ABI_FREE(redflg) 3614 3615 3616 DBG_EXIT("COLL") 3617 3618 end subroutine dfpt_ciflexoout
ABINIT/dfpt_ddmdqout [ Functions ]
NAME
dfpt_ddmdqout
FUNCTION
This subroutine gathers the different terms entering the first q derivative of the dynamical matrix, perfofms the transformation from reduced to cartesian coordinates and writes out the tensor in output files.
INPUTS
ddmdq_flg(natpert,natpert,nq1grad)=array that indicates which elements of the first q derivative of dynamical matrix have been calculated ddmdq_qgradhart(2,natpert,natpert,nq1grad)=electronic electrostatic contribution from the q-gradient of the Hartree potential ddmdqwf(2,natpert,natpert,nq1grad)=total wave function contribution to the first q derivative of dynamical matrix ddmdqwf_t1(2,natpert,natpert,nq1grad)=term 1 of the wave function contribution ddmdqwf_t2(2,natpert,natpert,nq1grad)=term 2 of the wave function contribution ddmdqwf_t3(2,natpert,natpert,nq1grad)=term 3 of the wave function contribution dyewdq(2,3,natom,3,natom,3)= First q-gradient of Ewald part of the dynamical matrix gprimd(3,3)=reciprocal space dimensional primitive translations kptopt=2 time reversal symmetry is enforced, 3 trs is not enforced (for debugging purposes) matom=number of atoms mpert=maximum number of perturbations natpert=number of atomic displacement perturbations nq1grad=number of q1 (q_{\gamma}) gradients pert_atdis(3,natpert)=array with the info for the electric field perturbations prtvol=volume of information to be printed. 1-> The different contributions to the quadrupole are printed. q1grad(3,nq1grad)=array with the info for the q1 (q_{\gamma}) gradients rprimd(3,3)=dimensional primitive translations in real space (bohr)
OUTPUT
d3etot(2,3,mpert,3,mpert,3,mpert)= matrix of the 3DTE
SIDE EFFECTS
NOTES
SOURCE
3661 subroutine dfpt_ddmdqout(ddmdq_flg,ddmdq_qgradhart,ddmdqwf,ddmdqwf_t1,ddmdqwf_t2,ddmdqwf_t3,d3etot, & 3662 & dyewdq,gprimd,kptopt,matom,mpert,natpert,nq1grad,pert_atdis,prtvol,q1grad,rprimd) 3663 3664 !Arguments ------------------------------------ 3665 !scalars 3666 integer,intent(in) :: kptopt,matom,mpert,natpert,nq1grad,prtvol 3667 real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert) 3668 3669 !arrays 3670 integer,intent(in) :: ddmdq_flg(natpert,natpert,nq1grad) 3671 integer,intent(in) :: pert_atdis(3,natpert) 3672 integer,intent(in) :: q1grad(3,nq1grad) 3673 real(dp),intent(inout) :: ddmdq_qgradhart(2,natpert,natpert,nq1grad) 3674 real(dp),intent(in) :: ddmdqwf(2,natpert,natpert,nq1grad) 3675 real(dp),intent(inout) :: ddmdqwf_t1(2,natpert,natpert,nq1grad) 3676 real(dp),intent(inout) :: ddmdqwf_t2(2,natpert,natpert,nq1grad) 3677 real(dp),intent(inout) :: ddmdqwf_t3(2,natpert,natpert,nq1grad) 3678 real(dp),intent(in) :: dyewdq(2,3,matom,3,matom,3) 3679 real(dp),intent(in) :: gprimd(3,3) 3680 real(dp),intent(in) :: rprimd(3,3) 3681 3682 !Local variables------------------------------- 3683 !scalars 3684 integer :: iatdir,iatom,iatpert,ii,iq1dir,iq1grad,iq1pert,jatdir,jatom,jatpert 3685 integer, parameter :: im=2,re=1 3686 real(dp) :: piezofrim,piezofrre,tmpim,tmpre 3687 character(len=500) :: msg 3688 3689 !arrays 3690 integer :: flg1(3),flg2(3) 3691 integer, allocatable :: cartflg(:,:,:,:,:),ddmdq_cartflg(:,:,:,:,:) 3692 real(dp) :: vec1(3),vec2(3) 3693 real(dp), allocatable :: ddmdq_cart(:,:,:,:,:,:),ddmdq_red(:,:,:,:) 3694 3695 !**************************************************************************** 3696 3697 DBG_ENTER("COLL") 3698 3699 !Open output files 3700 if (prtvol>=10) then 3701 open(unit=71,file='ddmdq_wf_t1.out',status='unknown',form='formatted',action='write') 3702 open(unit=72,file='ddmdq_wf_t2.out',status='unknown',form='formatted',action='write') 3703 open(unit=73,file='ddmdq_wf_t3.out',status='unknown',form='formatted',action='write') 3704 open(unit=74,file='ddmdq_ewald.out',status='unknown',form='formatted',action='write') 3705 open(unit=76,file='ddmdq_elecstic.out',status='unknown',form='formatted',action='write') 3706 end if 3707 3708 !Gather the different terms in the tensors and print the result 3709 ABI_MALLOC(ddmdq_red,(2,natpert,natpert,nq1grad)) 3710 3711 if (kptopt==3) then 3712 3713 iq1pert=matom+8 3714 do iq1grad=1,nq1grad 3715 iq1dir=q1grad(2,iq1grad) 3716 do jatpert=1,natpert 3717 jatom=pert_atdis(1,jatpert) 3718 jatdir=pert_atdis(2,jatpert) 3719 do iatpert=1,natpert 3720 iatom=pert_atdis(1,iatpert) 3721 iatdir=pert_atdis(2,iatpert) 3722 3723 if (ddmdq_flg(iatpert,jatpert,iq1grad)==1) then 3724 3725 !Calculate and save the third order energy derivative 3726 tmpre=ddmdq_qgradhart(re,iatpert,jatpert,iq1grad)+ddmdqwf(re,iatpert,jatpert,iq1grad)+& 3727 & half*dyewdq(re,iatdir,iatom,jatdir,jatom,iq1dir) 3728 tmpim=ddmdq_qgradhart(im,iatpert,jatpert,iq1grad)+ddmdqwf(im,iatpert,jatpert,iq1grad)+& 3729 & half*dyewdq(im,iatdir,iatom,jatdir,jatom,iq1dir) 3730 d3etot(re,iatdir,iatom,jatdir,jatom,iq1dir,iq1pert)=tmpre 3731 d3etot(im,iatdir,iatom,jatdir,jatom,iq1dir,iq1pert)=tmpim 3732 3733 !Calculate and write the q-gradient of the dynamical matrix (twice 3734 !the Energy derivative, see Gonze and Lee 1997) in the form of first 3735 !real-space moment of IFCs 3736 ddmdq_red(re,iatpert,jatpert,iq1grad)=-two*tmpim 3737 ddmdq_red(im,iatpert,jatpert,iq1grad)=two*tmpre 3738 3739 if (prtvol>=10) then 3740 !Write individual contributions 3741 write(71,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3742 & -two*ddmdqwf_t1(:,iatpert,jatpert,iq1grad) 3743 3744 write(72,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3745 & -two*ddmdqwf_t2(:,iatpert,jatpert,iq1grad) 3746 3747 write(73,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3748 & -two*ddmdqwf_t3(:,iatpert,jatpert,iq1grad) 3749 3750 write(74,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3751 & -dyewdq(:,iatdir,iatom,jatdir,jatom,iq1dir) 3752 3753 write(76,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3754 & -two*ddmdq_qgradhart(:,iatpert,jatpert,iq1grad) 3755 end if 3756 3757 end if 3758 3759 end do 3760 end do 3761 end do 3762 3763 else if (kptopt==2) then 3764 3765 iq1pert=matom+8 3766 do iq1grad=1,nq1grad 3767 iq1dir=q1grad(2,iq1grad) 3768 do jatpert=1,natpert 3769 jatom=pert_atdis(1,jatpert) 3770 jatdir=pert_atdis(2,jatpert) 3771 do iatpert=1,natpert 3772 iatom=pert_atdis(1,iatpert) 3773 iatdir=pert_atdis(2,iatpert) 3774 3775 if (ddmdq_flg(iatpert,jatpert,iq1grad)==1) then 3776 3777 !Calculate and save the third order energy derivative 3778 tmpim=ddmdq_qgradhart(im,iatpert,jatpert,iq1grad)+ddmdqwf(im,iatpert,jatpert,iq1grad)+& 3779 & half*dyewdq(im,iatdir,iatom,jatdir,jatom,iq1dir) 3780 d3etot(re,iatdir,iatom,jatdir,jatom,iq1dir,iq1pert)=zero 3781 d3etot(im,iatdir,iatom,jatdir,jatom,iq1dir,iq1pert)=tmpim 3782 3783 !Calculate and write the q-gradient of the dynamical matrix (twice 3784 !the Energy derivative, see Gonze and Lee 1997) in the form of first 3785 !real-space moment of IFCs 3786 ddmdq_red(re,iatpert,jatpert,iq1grad)=-two*tmpim 3787 ddmdq_red(im,iatpert,jatpert,iq1grad)=zero 3788 3789 if (prtvol>=10) then 3790 !Write individual contributions 3791 write(71,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3792 & -two*ddmdqwf_t1(im,iatpert,jatpert,iq1grad) 3793 3794 write(72,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3795 & -two*ddmdqwf_t2(im,iatpert,jatpert,iq1grad) 3796 3797 write(73,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3798 & -two*ddmdqwf_t3(im,iatpert,jatpert,iq1grad) 3799 3800 write(74,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3801 & -dyewdq(im,iatdir,iatom,jatdir,jatom,iq1dir) 3802 3803 write(76,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3804 & -two*ddmdq_qgradhart(im,iatpert,jatpert,iq1grad) 3805 end if 3806 3807 end if 3808 3809 end do 3810 end do 3811 end do 3812 3813 else 3814 3815 write(msg,"(1a)") 'kptopt must be 2 or 3 for the ddmdq calculation' 3816 ABI_BUG(msg) 3817 3818 end if 3819 3820 if (prtvol>=10) then 3821 close(71) 3822 close(72) 3823 close(73) 3824 close(74) 3825 close(76) 3826 end if 3827 3828 !Transformation to cartesian coordinates of the ddmdq 3829 ABI_MALLOC(ddmdq_cart,(2,matom,3,matom,3,3)) 3830 ABI_MALLOC(ddmdq_cartflg,(matom,3,matom,3,3)) 3831 ABI_MALLOC(cartflg,(matom,3,matom,3,3)) 3832 cartflg=0 3833 do iq1grad=1,nq1grad 3834 iq1dir=q1grad(2,iq1grad) 3835 do jatpert=1,natpert 3836 jatom=pert_atdis(1,jatpert) 3837 jatdir=pert_atdis(2,jatpert) 3838 do iatpert=1,natpert 3839 iatom=pert_atdis(1,iatpert) 3840 iatdir=pert_atdis(2,iatpert) 3841 ddmdq_cartflg(iatom,iatdir,jatom,jatdir,iq1dir)=ddmdq_flg(iatpert,jatpert,iq1grad) 3842 ddmdq_cart(:,iatom,iatdir,jatom,jatdir,iq1dir)=ddmdq_red(:,iatpert,jatpert,iq1grad) 3843 end do 3844 end do 3845 end do 3846 ABI_FREE(ddmdq_red) 3847 3848 !1st transform coordenates of the first atomic displacement derivative 3849 do iq1dir=1,3 3850 do jatdir=1,3 3851 do jatom=1,matom 3852 do ii=1,2 3853 do iatom=1,matom 3854 3855 do iatdir=1,3 3856 vec1(iatdir)=ddmdq_cart(ii,iatom,iatdir,jatom,jatdir,iq1dir) 3857 flg1(iatdir)=ddmdq_cartflg(iatom,iatdir,jatom,jatdir,iq1dir) 3858 end do 3859 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 3860 do iatdir=1,3 3861 ddmdq_cart(ii,iatom,iatdir,jatom,jatdir,iq1dir)=vec2(iatdir) 3862 cartflg(iatom,iatdir,jatom,jatdir,iq1dir)=flg2(iatdir) 3863 end do 3864 3865 end do 3866 end do 3867 end do 3868 end do 3869 end do 3870 3871 !2nd transform coordenates of the second atomic displacement derivative 3872 do iq1dir=1,3 3873 do iatdir=1,3 3874 do iatom=1,matom 3875 do ii=1,2 3876 do jatom=1,matom 3877 3878 do jatdir=1,3 3879 vec1(jatdir)=ddmdq_cart(ii,iatom,iatdir,jatom,jatdir,iq1dir) 3880 flg1(jatdir)=ddmdq_cartflg(iatom,iatdir,jatom,jatdir,iq1dir) 3881 end do 3882 call cart39(flg1,flg2,gprimd,jatom,matom,rprimd,vec1,vec2) 3883 do jatdir=1,3 3884 ddmdq_cart(ii,iatom,iatdir,jatom,jatdir,iq1dir)=vec2(jatdir) 3885 end do 3886 3887 end do 3888 end do 3889 end do 3890 end do 3891 end do 3892 3893 !3rd transform coordinates of the q-gradient (treat it as electric field) 3894 do jatdir=1,3 3895 do jatom=1,matom 3896 do iatdir=1,3 3897 do iatom=1,matom 3898 do ii=1,2 3899 3900 do iq1dir=1,3 3901 vec1(iq1dir)=ddmdq_cart(ii,iatom,iatdir,jatom,jatdir,iq1dir) 3902 flg1(iq1dir)=ddmdq_cartflg(iatom,iatdir,jatom,jatdir,iq1dir) 3903 end do 3904 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 3905 do iq1dir=1,3 3906 ddmdq_cart(ii,iatom,iatdir,jatom,jatdir,iq1dir)=vec2(iq1dir) 3907 end do 3908 3909 end do 3910 end do 3911 end do 3912 end do 3913 end do 3914 3915 !Write the tensor in cartesian coordinates 3916 write(ab_out,'(a)')' ' 3917 write(ab_out,'(a)')' First real-space moment of IFCs, in cartesian coordinates,' 3918 write(ab_out,'(a)')' iatom iatdir jatom jatddir qgrdir real part imaginary part' 3919 do iq1dir=1,3 3920 do jatdir=1,3 3921 do jatom=1,matom 3922 do iatdir=1,3 3923 do iatom=1,matom 3924 3925 if (cartflg(iatom,iatdir,jatom,jatdir,iq1dir)==1) then 3926 write(ab_out,'(5(i5,4x),2(1x,f20.10))') iatom, iatdir, jatom, jatdir, iq1dir, & 3927 & ddmdq_cart(:,iatom,iatdir,jatom,jatdir,iq1dir) 3928 end if 3929 3930 3931 end do 3932 end do 3933 end do 3934 end do 3935 write(ab_out,'(a)')' ' 3936 end do 3937 write(ab_out,'(80a)')('=',ii=1,80) 3938 3939 !Write the piezoelectric force-response tensor 3940 write(ab_out,'(a)')' ' 3941 write(ab_out,'(a)')' Piezoelectric force-response tensor, in cartesian coordinates ' 3942 write(ab_out,'(a)')' (from q-gradient of dynamical matrix),' 3943 write(ab_out,'(a)')' (for non-vanishing forces in the cell it lacks an improper contribution),' 3944 write(ab_out,'(a)')' iatom iatddir jatddir qgrdir real part imaginary part' 3945 do iq1dir=1,3 3946 do iatdir=1,3 3947 do iatom=1,matom 3948 do jatdir=1,3 3949 piezofrre=zero 3950 piezofrim=zero 3951 do jatom=1,matom 3952 3953 if (cartflg(iatom,iatdir,jatom,jatdir,iq1dir)==1) then 3954 piezofrre=piezofrre+ddmdq_cart(1,iatom,iatdir,jatom,jatdir,iq1dir) 3955 piezofrim=piezofrim+ddmdq_cart(2,iatom,iatdir,jatom,jatdir,iq1dir) 3956 end if 3957 3958 end do 3959 3960 write(ab_out,'(4(i5,4x),2(1x,f20.10))') iatom, iatdir, jatdir, iq1dir, & 3961 & piezofrre, piezofrim 3962 3963 end do 3964 end do 3965 end do 3966 write(ab_out,'(a)')' ' 3967 end do 3968 write(ab_out,'(80a)')('=',ii=1,80) 3969 3970 ABI_FREE(ddmdq_cart) 3971 ABI_FREE(ddmdq_cartflg) 3972 ABI_FREE(cartflg) 3973 3974 3975 DBG_EXIT("COLL") 3976 end subroutine dfpt_ddmdqout
ABINIT/dfpt_flexo [ Functions ]
NAME
dfpt_flexo
FUNCTION
This routine computes the elements of the flexoelectric tensor as: --> Electronic contribution: second q-gradient of the second mixed derivative of the energy w.r.t an electric field and a metric perturbation.
INPUTS
atindx(natom)=index table for atoms (see gstate.f) codvsn=code version doccde(mband*nkpt*nsppol)=derivative of occupancies wrt the energy dtfil <type(datafiles_type)>=variables related to files dtset <type(dataset_type)>=all input variables for this dataset dyewdq(2,3,natom,3,natom,3)= First q-gradient of Ewald part of the dynamical matrix dyewdqdq(2,3,natom,3,natom,3,3)= Second q-gradient of Ewald part of the dynamical matrix sumed over the second sublattice gmet(3,3)=reciprocal space metric tensor in bohr**-2. gprimd(3,3)=reciprocal space dimensional primitive translations kxc(nfft,nkxc)=exchange and correlation kernel mpert=maximum number of perturbations for output processing mpi_enreg=information about MPI parallelization nattyp(ntypat)= # atoms of each type. nfft=(effective) number of FFT grid points (for this proc) ngfft(1:18)=integer array with FFT box dimensions and other nkpt=number of k points in the full BZ nkxc=second dimension of the kxc array. If /=0, the XC kernel must be computed. nspden=number of spin-density components nsppol=1 for unpolarized, 2 for spin-polarized occ(mband*nkpt*nsppol)=occup number for each band (often 2) at each k point pawrhoij(my_natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data for the GS (DUMMY) pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data (DUMMY) pertsy(3,natom+6)=set of perturbations that form a basis for all other perturbations psps <type(pseudopotential_type)>=variables related to pseudopotentials rmet(3,3)=real space metric (bohr**2) rprimd(3,3)=dimensional primitive translations in real space (bohr) rhog(2,nfftf)=array for Fourier transform of GS electron density rhor(nfftf,nspden)=array for GS electron density in electrons/bohr**3. timrev=1 if time-reversal preserves the q wavevector; 0 otherwise. ucvol=unit cell volume in bohr**3. xred(3,natom)=reduced dimensionless atomic coordinates
OUTPUT
blkflg(3,mpert,3,mpert,3,mpert)= ( 1 if the element of the 3dte has been calculated ; 0 otherwise ) d3etot(2,3,mpert,3,mpert,3,mpert)= matrix of the 3DTE
SIDE EFFECTS
NOTES
SOURCE
1615 subroutine dfpt_flexo(atindx,blkflg,codvsn,d3etot,doccde,dtfil,dtset,dyewdq,dyewdqdq,& 1616 & gmet,gprimd,kxc,mpert,& 1617 & mpi_enreg,nattyp,nfft,ngfft,nkpt,nkxc,& 1618 & nspden,nsppol,occ,pawrhoij,pawtab,pertsy,psps,rmet,rprimd,rhog,rhor,& 1619 & timrev,ucvol,xred) 1620 1621 !Arguments ------------------------------------ 1622 !scalars 1623 integer,intent(in) :: mpert,nfft,nkpt,nkxc,nspden,nsppol,timrev 1624 real(dp),intent(in) :: ucvol 1625 character(len=8), intent(in) :: codvsn 1626 type(MPI_type),intent(inout) :: mpi_enreg 1627 type(datafiles_type),intent(in) :: dtfil 1628 type(dataset_type),intent(in) :: dtset 1629 type(hdr_type) :: hdr_den 1630 type(pseudopotential_type),intent(in) :: psps 1631 type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw) 1632 type(pawrhoij_type),intent(inout) :: pawrhoij(:) 1633 !arrays 1634 integer,intent(in) :: atindx(dtset%natom) 1635 integer,intent(inout) :: blkflg(3,mpert,3,mpert,3,mpert) 1636 integer,intent(in) :: nattyp(dtset%ntypat),ngfft(18) 1637 integer,intent(in) :: pertsy(3,dtset%natom+6) 1638 real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert) 1639 real(dp),intent(in) :: doccde(dtset%mband*nkpt*dtset%nsppol) 1640 real(dp),intent(in) :: dyewdq(2,3,dtset%natom,3,dtset%natom,3) 1641 real(dp),intent(inout) :: dyewdqdq(2,3,dtset%natom,3,3,3) 1642 real(dp),intent(in) :: gmet(3,3), gprimd(3,3) 1643 real(dp),intent(in) :: kxc(nfft,nkxc) 1644 real(dp),intent(in) :: occ(dtset%mband*nkpt*dtset%nsppol) 1645 real(dp),intent(in) :: rmet(3,3),rprimd(3,3) 1646 real(dp),intent(in) :: rhog(2,nfft),rhor(nfft,nspden) 1647 real(dp),intent(in) :: xred(3,dtset%natom) 1648 1649 !Local variables------------------------------- 1650 !scalars 1651 integer :: ask_accurate,bantot_rbz,bdtot_index,bdtot1_index 1652 integer :: cplex,formeig,forunit,gscase,icg 1653 integer :: ia1,iatdir,iatom,iatpert,iatpert_cnt,iatpol 1654 integer :: ii,iefipert,iefipert_cnt,ierr,ikg,ikpt,ikpt1,ilm 1655 integer :: iq1dir,iq2dir,iq1grad,iq1grad_cnt,iq1q2grad,iq1q2grad_var 1656 integer :: ireadwf0,isppol,istrdir,istrpert,istrtype,istrpert_cnt,istwf_k,itypat,jatpert,jj,ka,kb 1657 integer :: lw_flexo,master,matom,matpert,mcg,me,mgfft,mkmem_rbz,mpw,my_nkpt_rbz 1658 integer :: natpert,nband_k,nefipert,nfftot,nhat1grdim,nkpt_rbz 1659 integer :: npw_k,npw1_k,nq1grad,nq1q2grad,nstrpert,nsym1,n3xccc 1660 integer :: nylmgr,optene,option,optorth,optres 1661 integer :: pawread,pertcase,qcar,qdir,spaceworld 1662 integer :: usexcnhat,useylmgr 1663 integer :: mband_mem 1664 integer,parameter :: formeig1=1 1665 integer,parameter :: re=1,im=2 1666 real(dp) :: boxcut,delad,delag,delbd,delbg 1667 real(dp) :: doti,dotr,dum_scl,ecut_eff,ecut,etotal,fac,fermie,gsqcut,residm 1668 real(dp) :: vres2,wtk_k 1669 logical :: non_magnetic_xc 1670 character(len=500) :: msg 1671 character(len=fnlen) :: fi1o,fiwfatdis,fiwfstrain,fiwfefield,fiwfddk,fiwfdkdk 1672 type(ebands_t) :: bs_rbz 1673 type(hdr_type) :: hdr0 1674 type(wvl_data) :: wvl 1675 type(wffile_type) :: wffgs,wfftgs 1676 type(gs_hamiltonian_type) :: gs_hamkq 1677 1678 !arrays 1679 integer,save :: idx(12)=(/1,1,2,2,3,3,3,2,3,1,2,1/) 1680 integer,allocatable :: bz2ibz_smap(:,:) 1681 integer,allocatable :: ddmdq_flg(:,:,:,:,:),elflexoflg(:,:,:,:) 1682 integer,allocatable :: indkpt1(:), indkpt1_tmp(:) 1683 integer,allocatable :: indsy1(:,:,:),irrzon1(:,:,:) 1684 integer,allocatable :: istwfk_rbz(:),isdq_flg(:,:,:,:,:) 1685 integer,allocatable :: kg(:,:),kg_k(:,:) 1686 integer,allocatable :: nband_rbz(:),npwarr(:),npwtot(:) 1687 integer,allocatable :: pert_atdis(:,:),pert_atdis_tmp(:,:) 1688 integer,allocatable :: pert_efield(:,:),pert_efield_tmp(:,:) 1689 integer,allocatable :: pert_strain(:,:),pert_strain_tmp(:,:) 1690 integer,allocatable :: q1grad(:,:),q1grad_tmp(:,:),q1q2grad(:,:) 1691 integer,allocatable :: symaf1(:),symrc1(:,:,:),symrl1(:,:,:) 1692 real(dp) :: kpoint(3) 1693 real(dp),allocatable :: cg(:,:),doccde_rbz(:) 1694 real(dp),allocatable :: ddmdq_qgradhart(:,:,:,:) 1695 real(dp),allocatable :: ddmdqwf(:,:,:,:),ddmdqwf_k(:,:,:,:) 1696 real(dp),allocatable :: ddmdqwf_t1(:,:,:,:),ddmdqwf_t1_k(:,:,:,:) 1697 real(dp),allocatable :: ddmdqwf_t2(:,:,:,:),ddmdqwf_t2_k(:,:,:,:) 1698 real(dp),allocatable :: ddmdqwf_t3(:,:,:,:),ddmdqwf_t3_k(:,:,:,:) 1699 real(dp),allocatable :: eigen0(:) 1700 real(dp),allocatable :: elflexowf(:,:,:,:,:),elflexowf_k(:,:,:,:,:) 1701 real(dp),allocatable :: elflexowf_t1(:,:,:,:,:),elflexowf_t1_k(:,:,:,:,:) 1702 real(dp),allocatable :: elflexowf_t2(:,:,:,:,:),elflexowf_t2_k(:,:,:,:,:) 1703 real(dp),allocatable :: elflexowf_t3(:,:,:,:,:),elflexowf_t3_k(:,:,:,:,:) 1704 real(dp),allocatable :: elflexowf_t4(:,:,:,:,:),elflexowf_t4_k(:,:,:,:,:) 1705 real(dp),allocatable :: elflexowf_t5(:,:,:,:,:),elflexowf_t5_k(:,:,:,:,:) 1706 real(dp),allocatable :: elqgradhart(:,:,:,:,:) 1707 real(dp),allocatable :: frwfdq(:,:,:,:,:,:),frwfdq_k(:,:,:,:,:,:) 1708 real(dp),allocatable :: isdq_qgradhart(:,:,:,:,:,:) 1709 real(dp),allocatable :: isdqwf(:,:,:,:,:,:),isdqwf_k(:,:,:,:,:,:) 1710 real(dp),allocatable :: isdqwf_t1(:,:,:,:,:,:),isdqwf_t1_k(:,:,:,:,:,:) 1711 real(dp),allocatable :: isdqwf_t2(:,:,:,:,:,:),isdqwf_t2_k(:,:,:,:,:,:) 1712 real(dp),allocatable :: isdqwf_t3(:,:,:,:,:,:),isdqwf_t3_k(:,:,:,:,:,:) 1713 real(dp),allocatable :: isdqwf_t4(:,:,:,:,:,:),isdqwf_t4_k(:,:,:,:,:,:) 1714 real(dp),allocatable :: isdqwf_t5(:,:,:,:,:,:),isdqwf_t5_k(:,:,:,:,:,:) 1715 real(dp),allocatable :: kpt_rbz(:,:) 1716 real(dp),allocatable :: nhat(:,:),nhat1(:,:),nhat1gr(:,:,:) 1717 real(dp),allocatable :: occ_k(:),occ_rbz(:) 1718 real(dp),allocatable :: ph1d(:,:),phnons1(:,:,:) 1719 real(dp),allocatable :: rhog1_tmp(:,:),rhog1_atdis(:,:,:) 1720 real(dp),allocatable :: rhog1_efield(:,:,:),rhor1_atdis(:,:,:),rhor1_efield(:,:,:) 1721 real(dp),allocatable :: rhor1_cplx(:,:),rhor1_tmp(:,:),rhor1_real(:,:) 1722 real(dp),allocatable :: rhor1_strain(:,:,:) 1723 real(dp),allocatable :: vhartr1(:),vhxc1_atdis(:,:),vhxc1_efield(:,:),vhxc1_strain(:,:) 1724 real(dp),allocatable :: vpsp1(:),vqgradhart(:),vresid1(:,:) 1725 real(dp),allocatable :: vxc1(:,:),vxc1dq(:,:),vxc1dqc(:,:,:,:) 1726 real(dp),allocatable :: dum_vxc(:,:) 1727 real(dp),allocatable :: wtk_folded(:), wtk_rbz(:) 1728 real(dp),allocatable,target :: vtrial1(:,:) 1729 real(dp),allocatable :: tnons1(:,:) 1730 real(dp),allocatable :: xccc3d1(:) 1731 real(dp),allocatable :: ylm(:,:),ylm_k(:,:),ylmgr(:,:,:),ylmgr_k(:,:,:) 1732 type(pawrhoij_type),allocatable :: pawrhoij_read(:) 1733 type(wfk_t),allocatable :: wfk_t_atdis(:),wfk_t_efield(:),wfk_t_ddk(:) 1734 type(wfk_t),allocatable :: wfk_t_dkdk(:),wfk_t_strain(:,:) 1735 ! ************************************************************************* 1736 1737 DBG_ENTER("COLL") 1738 1739 !Anounce start of flexoelectric tensor calculation 1740 write(msg, '(a,80a,a,a,a)' ) ch10,('=',ii=1,80),ch10,& 1741 & ' ==> Compute Flexoelectric Tensor Related Magnitudes <== ',ch10 1742 call wrtout(std_out,msg,'COLL') 1743 call wrtout(ab_out,msg,'COLL') 1744 1745 !Init parallelism 1746 spaceworld=mpi_enreg%comm_cell 1747 me=mpi_enreg%me_kpt 1748 master=0 1749 1750 !Get FFT grid(s) sizes (be careful !) See NOTES in the comments at the beginning of respfn.F90 1751 mgfft=dtset%mgfft 1752 ecut=dtset%ecut 1753 ecut_eff=ecut*(dtset%dilatmx)**2 1754 1755 !Compute large sphere cut-off gsqcut 1756 call getcut(boxcut,ecut,gmet,gsqcut,dtset%iboxcut,std_out,dtset%qptn,ngfft) 1757 1758 !Various initializations 1759 lw_flexo=dtset%lw_flexo 1760 cplex=2-timrev 1761 matom=dtset%natom 1762 usexcnhat=0 1763 n3xccc=0 1764 nfftot=ngfft(1)*ngfft(2)*ngfft(3) 1765 non_magnetic_xc=.true. 1766 1767 !Generate the 1-dimensional phases 1768 ABI_MALLOC(ph1d,(2,3*(2*dtset%mgfft+1)*dtset%natom)) 1769 call getph(atindx,dtset%natom,dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3),ph1d,xred) 1770 1771 !################# PERTURBATIONS AND q-GRADIENTS LABELLING ############################ 1772 1773 !Determine which atomic displacement, electric field, strain and q-gradient directions 1774 !have to be evaluated taking into account the perturbation symmetries 1775 matpert=dtset%natom*3 1776 1777 !Atomic displacement 1778 if (lw_flexo==1.or.lw_flexo==3.or.lw_flexo==4) then 1779 ABI_MALLOC(pert_atdis_tmp,(3,matpert)) 1780 pert_atdis_tmp=0 1781 iatpert_cnt=0 1782 do iatpol=1,matom 1783 do iatdir=1,3 1784 if (pertsy(iatdir,iatpol)==1) then 1785 iatpert_cnt=iatpert_cnt+1 1786 pert_atdis_tmp(1,iatpert_cnt)=iatpol !atom displaced 1787 pert_atdis_tmp(2,iatpert_cnt)=iatdir !direction of displacement 1788 pert_atdis_tmp(3,iatpert_cnt)=(iatpol-1)*3+iatdir !like pertcase in dfpt_loopert.f90 1789 end if 1790 end do 1791 end do 1792 natpert=iatpert_cnt 1793 ABI_MALLOC(pert_atdis,(3,natpert)) 1794 do iatpert=1,natpert 1795 pert_atdis(:,iatpert)=pert_atdis_tmp(:,iatpert) 1796 end do 1797 ABI_FREE(pert_atdis_tmp) 1798 end if 1799 1800 !Electric field 1801 if (lw_flexo==1.or.lw_flexo==2) then 1802 ABI_MALLOC(pert_efield_tmp,(3,3)) 1803 pert_efield_tmp=0 1804 iefipert_cnt=0 1805 do iefipert=1,3 1806 if (pertsy(iefipert,dtset%natom+2)==1) then 1807 iefipert_cnt=iefipert_cnt+1 1808 pert_efield_tmp(1,iefipert_cnt)=dtset%natom+2 !electric field pert 1809 pert_efield_tmp(2,iefipert_cnt)=iefipert !electric field direction 1810 pert_efield_tmp(3,iefipert_cnt)=matpert+3+iefipert !like pertcase in dfpt_loopert.f90 1811 end if 1812 end do 1813 nefipert=iefipert_cnt 1814 ABI_MALLOC(pert_efield,(3,nefipert)) 1815 do iefipert=1,nefipert 1816 pert_efield(:,iefipert)=pert_efield_tmp(:,iefipert) 1817 end do 1818 ABI_FREE(pert_efield_tmp) 1819 end if 1820 1821 !ddk 1822 !The q1grad is related with the response to the ddk 1823 ABI_MALLOC(q1grad_tmp,(3,3)) 1824 q1grad_tmp=0 1825 iq1grad_cnt=0 1826 do iq1grad=1,3 1827 if (pertsy(iq1grad,dtset%natom+1)==1) then 1828 iq1grad_cnt=iq1grad_cnt+1 1829 q1grad_tmp(1,iq1grad_cnt)=dtset%natom+1 !ddk perturbation 1830 q1grad_tmp(2,iq1grad_cnt)=iq1grad !ddk direction 1831 q1grad_tmp(3,iq1grad_cnt)=matpert+iq1grad !like pertcase in dfpt_loopert.f90 1832 end if 1833 end do 1834 nq1grad=iq1grad_cnt 1835 ABI_MALLOC(q1grad,(3,nq1grad)) 1836 do iq1grad=1,nq1grad 1837 q1grad(:,iq1grad)=q1grad_tmp(:,iq1grad) 1838 end do 1839 ABI_FREE(q1grad_tmp) 1840 1841 !d2_dkdk 1842 !For the evaluation of the 2nd order q-gradient, the 9 directios are activated because 1843 !currently the program calculates by defect all the components of the d2_dkdk perturbation. 1844 !TODO: This will have to be modified in the future when ABINIT enables to calculate specific 1845 !components of the d2_dkdk 1846 if (lw_flexo==1.or.lw_flexo==2) then 1847 nq1q2grad=9 1848 ABI_MALLOC(q1q2grad,(4,nq1q2grad)) 1849 do iq1q2grad=1,nq1q2grad 1850 call rf2_getidirs(iq1q2grad,iq1dir,iq2dir) 1851 if (iq1dir==iq2dir) then 1852 q1q2grad(1,iq1q2grad)=dtset%natom+10 !d2_dkdk perturbation diagonal elements 1853 else 1854 q1q2grad(1,iq1q2grad)=dtset%natom+11 !d2_dkdk perturbation off-diagonal elements 1855 end if 1856 q1q2grad(2,iq1q2grad)=iq1dir !dq1 direction 1857 q1q2grad(3,iq1q2grad)=iq2dir !dq2 direction 1858 iq1q2grad_var=iq1q2grad 1859 if (iq1q2grad>6) iq1q2grad_var=iq1q2grad-3 !Lower=Upper diagonal triangle matrix 1860 q1q2grad(4,iq1q2grad)=iq1q2grad_var+(dtset%natom+6)*3 !like pertcase in dfpt_loopert.f90 1861 end do 1862 end if 1863 1864 !Strain perturbation 1865 if (lw_flexo==1.or.lw_flexo==2.or.lw_flexo==4) then 1866 ABI_MALLOC(pert_strain_tmp,(6,9)) 1867 pert_strain_tmp=0 1868 !tmp uniaxial components 1869 istrpert_cnt=0 1870 do istrdir=1,3 1871 if (pertsy(istrdir,dtset%natom+3)==1) then 1872 istrpert_cnt=istrpert_cnt+1 1873 ka=idx(2*istrdir-1);kb=idx(2*istrdir) 1874 pert_strain_tmp(1,istrpert_cnt)=dtset%natom+3 !Uniaxial strain perturbation 1875 pert_strain_tmp(2,istrpert_cnt)=istrdir !Uniaxial strain case 1876 pert_strain_tmp(3,istrpert_cnt)=ka !Strain direction 1 1877 pert_strain_tmp(4,istrpert_cnt)=kb !Strain direction 2 1878 pert_strain_tmp(5,istrpert_cnt)=matpert+6+istrdir !like pertcase in dfpt_loopert.f90 1879 pert_strain_tmp(6,istrpert_cnt)=istrdir !Indexing for the second q-gradient of the metric Hamiltonian 1880 end if 1881 end do 1882 !tmp shear components 1883 do istrdir=1,3 1884 if (pertsy(istrdir,dtset%natom+4)==1) then 1885 istrpert_cnt=istrpert_cnt+1 1886 ka=idx(2*(istrdir+3)-1);kb=idx(2*(istrdir+3)) 1887 pert_strain_tmp(1,istrpert_cnt)=dtset%natom+4 !Shear strain perturbation 1888 pert_strain_tmp(2,istrpert_cnt)=istrdir !Shear strain case 1889 pert_strain_tmp(3,istrpert_cnt)=ka !Strain direction 1 1890 pert_strain_tmp(4,istrpert_cnt)=kb !Strain direction 2 1891 pert_strain_tmp(5,istrpert_cnt)=matpert+9+istrdir !like pertcase in dfpt_loopert.f90 1892 pert_strain_tmp(6,istrpert_cnt)=3+istrdir !Indexing for the second q-gradient of the metric Hamiltonian 1893 end if 1894 end do 1895 do istrdir=1,3 1896 if (pertsy(istrdir,dtset%natom+4)==1) then 1897 istrpert_cnt=istrpert_cnt+1 1898 ka=idx(2*(istrdir+3)-1);kb=idx(2*(istrdir+3)) 1899 pert_strain_tmp(1,istrpert_cnt)=dtset%natom+4 !Shear strain perturbation 1900 pert_strain_tmp(2,istrpert_cnt)=istrdir !Shear strain case 1901 pert_strain_tmp(3,istrpert_cnt)=kb !Strain direction 1 1902 pert_strain_tmp(4,istrpert_cnt)=ka !Strain direction 2 1903 pert_strain_tmp(5,istrpert_cnt)=matpert+9+istrdir !like pertcase in dfpt_loopert.f90 1904 pert_strain_tmp(6,istrpert_cnt)=6+istrdir !Indexing for the second q-gradient of the metric Hamiltonian 1905 end if 1906 end do 1907 nstrpert=istrpert_cnt 1908 ABI_MALLOC(pert_strain,(6,nstrpert)) 1909 do istrpert=1,nstrpert 1910 pert_strain(:,istrpert)=pert_strain_tmp(:,istrpert) 1911 end do 1912 ABI_FREE(pert_strain_tmp) 1913 end if 1914 1915 !################# ELECTROSTATIC CONTRIBUTIONS ####################################### 1916 1917 !This is necessary to deactivate paw options in the dfpt_rhotov routine 1918 ABI_MALLOC(pawrhoij_read,(0)) 1919 pawread=0 1920 nhat1grdim=0 1921 ABI_MALLOC(nhat1gr,(0,0,0)) 1922 ABI_MALLOC(nhat,(nfft,nspden)) 1923 nhat=zero 1924 ABI_MALLOC(nhat1,(cplex*nfft,nspden)) 1925 nhat1=zero 1926 1927 !Read the first order densities response from a disk file, calculates the FFT 1928 !(rhog1_tmp) and the first order Hartree and xc potentials(vhxc1_pert). 1929 !TODO: In the call to read_rhor there is a security option that compares with the header 1930 !hdr. Not activated at this moment. 1931 ABI_MALLOC(rhog1_tmp,(2,nfft)) 1932 ABI_MALLOC(rhor1_tmp,(cplex*nfft,nspden)) 1933 ABI_MALLOC(rhor1_real,(1*nfft,nspden)) 1934 ABI_MALLOC(vhartr1,(cplex*nfft)) 1935 ABI_MALLOC(vpsp1,(cplex*nfft)) 1936 ABI_MALLOC(vtrial1,(cplex*nfft,nspden)) 1937 ABI_MALLOC(vresid1,(cplex*nfft,nspden)) 1938 ABI_MALLOC(vxc1,(cplex*nfft,nspden)) 1939 ABI_MALLOC(dum_vxc,(nfft,nspden)) 1940 ABI_MALLOC(xccc3d1,(cplex*n3xccc)) 1941 vpsp1=zero; dum_vxc=zero 1942 optene=0; optres=1 1943 1944 !Atomic displacement 1945 if (lw_flexo==1.or.lw_flexo==3.or.lw_flexo==4) then 1946 ABI_MALLOC(rhor1_atdis,(natpert,cplex*nfft,nspden)) 1947 ABI_MALLOC(rhog1_atdis,(natpert,2,nfft)) 1948 ABI_MALLOC(vhxc1_atdis,(natpert,cplex*nfft)) 1949 vtrial1=zero 1950 do iatpert= 1, natpert 1951 iatpol=pert_atdis(1,iatpert) 1952 iatdir=pert_atdis(2,iatpert) 1953 pertcase=pert_atdis(3,iatpert) 1954 1955 !Reads a real first order density 1956 call appdig(pertcase,dtfil%fildens1in,fi1o) 1957 call read_rhor(fi1o, 1, nspden, nfft, ngfft, pawread, mpi_enreg, rhor1_real, & 1958 & hdr_den, pawrhoij_read, spaceworld) 1959 call hdr_den%free() 1960 1961 !Perform FFT rhor1 to rhog1 1962 call fourdp(cplex,rhog1_tmp,rhor1_real,-1,mpi_enreg,nfft,1,ngfft,0) 1963 1964 !Accumulate density in meaningful complex arrays 1965 if (timrev==0) then 1966 do ii=1,nfft 1967 jj=ii*2 1968 rhor1_tmp(jj-1,:)=rhor1_real(ii,:) 1969 rhor1_tmp(jj,:)=zero 1970 end do 1971 else if (timrev==1) then 1972 rhor1_tmp(:,:)=rhor1_real(:,:) 1973 end if 1974 rhog1_atdis(iatpert,:,:)=rhog1_tmp(:,:) 1975 rhor1_atdis(iatpert,:,:)=rhor1_tmp(:,:) 1976 1977 !Calculate first order Hartree and xc potentials 1978 call dfpt_rhotov(cplex,dum_scl,dum_scl,dum_scl,dum_scl,dum_scl, & 1979 & gsqcut,iatdir,iatpol,& 1980 & dtset%ixc,kxc,mpi_enreg,dtset%natom,nfft,ngfft,nhat,nhat1,nhat1gr,nhat1grdim,nkxc,& 1981 & nspden,n3xccc,non_magnetic_xc,optene,optres,dtset%qptn,rhog,rhog1_tmp,rhor,rhor1_tmp,& 1982 & rprimd,ucvol,psps%usepaw,usexcnhat,vhartr1,vpsp1,vresid1,vres2,vtrial1,dum_vxc,vxc1,& 1983 & xccc3d1,dtset%ixcrot) 1984 1985 !Accumulate the potential in meaningful arrays 1986 vhxc1_atdis(iatpert,:)=vtrial1(:,nspden) 1987 1988 end do 1989 end if 1990 1991 !Electric field 1992 if (lw_flexo==1.or.lw_flexo==2) then 1993 ABI_MALLOC(rhog1_efield,(nefipert,2,nfft)) 1994 ABI_MALLOC(rhor1_efield,(nefipert,cplex*nfft,nspden)) 1995 ABI_MALLOC(vhxc1_efield,(nefipert,cplex*nfft)) 1996 vtrial1=zero 1997 do iefipert=1,nefipert 1998 pertcase=pert_efield(3,iefipert) 1999 2000 !Reads a real first order density 2001 call appdig(pertcase,dtfil%fildens1in,fi1o) 2002 call read_rhor(fi1o, 1, nspden, nfft, ngfft, pawread, mpi_enreg, rhor1_real, & 2003 & hdr_den, pawrhoij_read, spaceworld) 2004 call hdr_den%free() 2005 2006 !Perform FFT rhor1 to rhog1 2007 call fourdp(cplex,rhog1_tmp,rhor1_real,-1,mpi_enreg,nfft,1,ngfft,0) 2008 2009 !Accumulate density in meaningful complex arrays 2010 if (timrev==0) then 2011 do ii=1,nfft 2012 jj=ii*2 2013 rhor1_tmp(jj-1,:)=rhor1_real(ii,:) 2014 rhor1_tmp(jj,:)=zero 2015 end do 2016 else if (timrev==1) then 2017 rhor1_tmp(:,:)=rhor1_real(:,:) 2018 end if 2019 rhog1_efield(iefipert,:,:)=rhog1_tmp(:,:) 2020 rhor1_efield(iefipert,:,:)=rhor1_tmp(:,:) 2021 2022 !Calculate first order Hartree and xc potentials 2023 call dfpt_rhotov(cplex,dum_scl,dum_scl,dum_scl,dum_scl,dum_scl, & 2024 & gsqcut,pert_efield(2,iefipert),dtset%natom+2,& 2025 & dtset%ixc,kxc,mpi_enreg,dtset%natom,nfft,ngfft,nhat,nhat1,nhat1gr,nhat1grdim,nkxc,& 2026 & nspden,n3xccc,non_magnetic_xc,optene,optres,dtset%qptn,rhog,rhog1_tmp,rhor,rhor1_tmp,& 2027 & rprimd,ucvol,psps%usepaw,usexcnhat,vhartr1,vpsp1,vresid1,vres2,vtrial1,dum_vxc,vxc1,& 2028 & xccc3d1,dtset%ixcrot) 2029 2030 !Accumulate the potential in meaningful arrays 2031 vhxc1_efield(iefipert,:)=vtrial1(:,nspden) 2032 2033 end do 2034 endif 2035 2036 !Strain 2037 if (lw_flexo==1.or.lw_flexo==2.or.lw_flexo==4) then 2038 ABI_MALLOC(rhor1_strain,(nstrpert,cplex*nfft,nspden)) 2039 ABI_MALLOC(vhxc1_strain,(nstrpert,cplex*nfft)) 2040 vtrial1=zero 2041 do istrpert= 1, nstrpert 2042 istrtype=pert_strain(1,istrpert) 2043 istrdir=pert_strain(2,istrpert) 2044 pertcase=pert_strain(5,istrpert) 2045 2046 !Reads a real first order density 2047 call appdig(pertcase,dtfil%fildens1in,fi1o) 2048 call read_rhor(fi1o, 1, nspden, nfft, ngfft, pawread, mpi_enreg, rhor1_real, & 2049 & hdr_den, pawrhoij_read, spaceworld) 2050 call hdr_den%free() 2051 2052 !Perform FFT rhor1 to rhog1 2053 call fourdp(cplex,rhog1_tmp,rhor1_real,-1,mpi_enreg,nfft,1,ngfft,0) 2054 2055 !Accumulate density in meaningful complex arrays 2056 if (timrev==0) then 2057 do ii=1,nfft 2058 jj=ii*2 2059 rhor1_tmp(jj-1,:)=rhor1_real(ii,:) 2060 rhor1_tmp(jj,:)=zero 2061 end do 2062 else if (timrev==1) then 2063 rhor1_tmp(:,:)=rhor1_real(:,:) 2064 end if 2065 rhor1_strain(istrpert,:,:)=rhor1_tmp(:,:) 2066 2067 !Calculate first order Hartree and xc potentials 2068 call dfpt_rhotov(cplex,dum_scl,dum_scl,dum_scl,dum_scl,dum_scl, & 2069 & gsqcut,istrdir,istrtype,& 2070 & dtset%ixc,kxc,mpi_enreg,dtset%natom,nfft,ngfft,nhat,nhat1,nhat1gr,nhat1grdim,nkxc,& 2071 & nspden,n3xccc,non_magnetic_xc,optene,optres,dtset%qptn,rhog,rhog1_tmp,rhor,rhor1_tmp,& 2072 & rprimd,ucvol,psps%usepaw,usexcnhat,vhartr1,vpsp1,vresid1,vres2,vtrial1,dum_vxc,vxc1,& 2073 & xccc3d1,dtset%ixcrot) 2074 2075 !Accumulate the potential in meaningful arrays 2076 vhxc1_strain(istrpert,:)=vtrial1(:,nspden) 2077 2078 end do 2079 end if 2080 2081 !These arrays will not be used anymore (for the moment) 2082 ABI_FREE(rhor1_real) 2083 ABI_FREE(rhor1_tmp) 2084 ABI_FREE(vhartr1) 2085 ABI_FREE(vpsp1) 2086 ABI_FREE(vtrial1) 2087 ABI_FREE(vresid1) 2088 ABI_FREE(vxc1) 2089 ABI_FREE(dum_vxc) 2090 ABI_FREE(xccc3d1) 2091 2092 ABI_FREE(pawrhoij_read) 2093 ABI_FREE(nhat1gr) 2094 ABI_FREE(nhat) 2095 ABI_FREE(nhat1) 2096 2097 !!Calculate the electrostatic term from the q-gradient of the Hxc kernel 2098 ABI_MALLOC(vqgradhart,(2*nfft)) 2099 ABI_MALLOC(rhor1_cplx,(2*nfft,nspden)) 2100 rhor1_cplx=zero 2101 if (nkxc == 7) then 2102 ABI_MALLOC(vxc1dq,(2*nfft,nspden)) 2103 ABI_MALLOC(rhor1_tmp,(cplex*nfft,nspden)) 2104 end if 2105 2106 !Electronic contribution 2107 if (lw_flexo==1.or.lw_flexo==2) then 2108 !If GGA xc first calculate the Cartesian q-gradient of the xc kernel 2109 if (nkxc == 7) then 2110 ABI_MALLOC(vxc1dqc,(2*nfft,nspden,nefipert,3)) 2111 do qcar=1,3 2112 do iefipert=1,nefipert 2113 rhor1_tmp(:,:)=rhor1_efield(iefipert,:,:) 2114 call dfpt_mkvxcggadq(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,nkxc,nspden,qcar,rhor1_tmp,vxc1dq) 2115 vxc1dqc(:,:,iefipert,qcar)=vxc1dq(:,:) 2116 end do 2117 end do 2118 end if 2119 2120 ABI_MALLOC(elqgradhart,(2,3,3,3,3)) 2121 ABI_MALLOC(elflexoflg,(3,3,3,3)) 2122 elflexoflg=0 2123 do iq1grad=1,nq1grad 2124 qdir=q1grad(2,iq1grad) 2125 do iefipert=1,nefipert 2126 2127 !Calculate the gradient of the potential generated by the first order electric field density 2128 rhog1_tmp(:,:)=rhog1_efield(iefipert,:,:) 2129 call hartredq(2,gmet,gsqcut,mpi_enreg,nfft,ngfft,qdir,rhog1_tmp,vqgradhart) 2130 2131 !To ckeck 2132 !call appdig(pert_efield(3,iefipert)+q1grad(3,iq1grad),"Gradient_Hartree_potential",fi1o) 2133 !call fftdatar_write_from_hdr("first_order_potential",fi1o,dtset%iomode,hdr_den,& 2134 ! & ngfft,cplex,nfft,nspden,vqgradhart,mpi_enreg) 2135 2136 !If GGA convert the gradient of xc kernel to reduced coordinates and incorporate it to the Hartree part 2137 if (nkxc == 7) then 2138 vxc1dq=zero 2139 do qcar=1,3 2140 vxc1dq(:,:)=vxc1dq(:,:) + gprimd(qcar,qdir) * & 2141 & vxc1dqc(:,:,iefipert,qcar) 2142 end do 2143 vqgradhart(:)=vqgradhart(:)+vxc1dq(:,1) 2144 end if 2145 2146 do istrpert=1,nstrpert 2147 2148 !Calculate the electrostatic energy term with the first order strain density 2149 !I need a cplex density for the dotprod_vn 2150 do ii=1,nfft 2151 jj=ii*2 2152 rhor1_cplx(jj-1,:)=rhor1_strain(istrpert,ii,:) 2153 end do 2154 2155 call dotprod_vn(2,rhor1_cplx,dotr,doti,nfft,nfftot,nspden,2,vqgradhart,ucvol) 2156 elqgradhart(re,pert_efield(2,iefipert),q1grad(2,iq1grad),pert_strain(3,istrpert),pert_strain(4,istrpert))=dotr*half 2157 elqgradhart(im,pert_efield(2,iefipert),q1grad(2,iq1grad),pert_strain(3,istrpert),pert_strain(4,istrpert))=doti*half 2158 elflexoflg(pert_efield(2,iefipert),q1grad(2,iq1grad),pert_strain(3,istrpert),pert_strain(4,istrpert))=1 2159 2160 blkflg(pert_efield(2,iefipert),pert_efield(1,iefipert), & 2161 & pert_strain(2,istrpert),pert_strain(1,istrpert), & 2162 & q1grad(2,iq1grad),matom+8)=1 2163 2164 end do 2165 end do 2166 end do 2167 if (nkxc == 7) then 2168 ABI_FREE(vxc1dqc) 2169 end if 2170 end if 2171 2172 !Calculate here the Cartesian q-gradient of the GGA xc kernel which is the same 2173 !for the other two spatial-dispersion properties 2174 if (lw_flexo==1.or.lw_flexo==3.or.lw_flexo==4) then 2175 if (nkxc == 7) then 2176 ABI_MALLOC(vxc1dqc,(2*nfft,nspden,natpert,3)) 2177 do qcar=1,3 2178 do iatpert=1,natpert 2179 rhor1_tmp(:,:)=rhor1_atdis(iatpert,:,:) 2180 call dfpt_mkvxcggadq(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,nkxc,nspden,qcar,rhor1_tmp,vxc1dq) 2181 vxc1dqc(:,:,iatpert,qcar)=vxc1dq(:,:) 2182 end do 2183 end do 2184 ABI_FREE(rhor1_tmp) 2185 end if 2186 end if 2187 2188 !1st q-gradient of DM contribution 2189 if (lw_flexo==1.or.lw_flexo==3) then 2190 ABI_MALLOC(ddmdq_qgradhart,(2,natpert,natpert,nq1grad)) 2191 ABI_MALLOC(ddmdq_flg,(matom,3,matom,3,3)) 2192 ddmdq_flg=0 2193 do iq1grad=1,nq1grad 2194 qdir=q1grad(2,iq1grad) 2195 do iatpert=1,natpert 2196 2197 rhog1_tmp(:,:)=rhog1_atdis(iatpert,:,:) 2198 call hartredq(2,gmet,gsqcut,mpi_enreg,nfft,ngfft,qdir,rhog1_tmp,vqgradhart) 2199 2200 !If GGA convert the gradient of xc kernel to reduced coordinates and incorporate it to the Hartree part 2201 if (nkxc == 7) then 2202 vxc1dq=zero 2203 do qcar=1,3 2204 vxc1dq(:,:)=vxc1dq(:,:) + gprimd(qcar,qdir) * & 2205 & vxc1dqc(:,:,iatpert,qcar) 2206 end do 2207 vqgradhart(:)=vqgradhart(:)+vxc1dq(:,1) 2208 end if 2209 2210 !TODO:Maybe it is only necessary to compute half of these elements by symmetry 2211 do jatpert=1,natpert 2212 2213 !Calculate the electrostatic energy term with the first order electric field density 2214 !I need a cplex density for the dotprod_vn 2215 do ii=1,nfft 2216 jj=ii*2 2217 rhor1_cplx(jj-1,:)=rhor1_atdis(jatpert,ii,:) 2218 end do 2219 2220 call dotprod_vn(2,rhor1_cplx,dotr,doti,nfft,nfftot,nspden,2,vqgradhart,ucvol) 2221 ddmdq_qgradhart(re,iatpert,jatpert,iq1grad)=dotr*half 2222 ddmdq_qgradhart(im,iatpert,jatpert,iq1grad)=doti*half 2223 ddmdq_flg(pert_atdis(1,iatpert),pert_atdis(2,iatpert),& 2224 & pert_atdis(1,jatpert),pert_atdis(2,jatpert),q1grad(2,iq1grad))=1 2225 2226 blkflg(pert_atdis(2,iatpert),pert_atdis(1,iatpert), & 2227 & pert_atdis(2,jatpert),pert_atdis(1,jatpert), & 2228 & q1grad(2,iq1grad),matom+8)=1 2229 2230 end do 2231 end do 2232 end do 2233 end if 2234 2235 !1st g-gradient of internal strain tensor contribution 2236 if (lw_flexo==1.or.lw_flexo==4) then 2237 ABI_MALLOC(isdq_qgradhart,(2,matom,3,3,3,3)) 2238 ABI_MALLOC(isdq_flg,(matom,3,3,3,3)) 2239 isdq_flg=0 2240 do iq1grad=1,nq1grad 2241 qdir=q1grad(2,iq1grad) 2242 do iatpert=1,natpert 2243 2244 rhog1_tmp(:,:)=rhog1_atdis(iatpert,:,:) 2245 call hartredq(2,gmet,gsqcut,mpi_enreg,nfft,ngfft,qdir,rhog1_tmp,vqgradhart) 2246 2247 !If GGA convert the gradient of xc kernel to reduced coordinates and incorporate it to the Hartree part 2248 if (nkxc == 7) then 2249 vxc1dq=zero 2250 do qcar=1,3 2251 vxc1dq(:,:)=vxc1dq(:,:) + gprimd(qcar,qdir) * & 2252 & vxc1dqc(:,:,iatpert,qcar) 2253 end do 2254 vqgradhart(:)=vqgradhart(:)+vxc1dq(:,1) 2255 end if 2256 2257 do istrpert=1,nstrpert 2258 2259 !Calculate the electrostatic energy term with the first order strain density 2260 !I need a cplex density for the dotprod_vn 2261 do ii=1,nfft 2262 jj=ii*2 2263 rhor1_cplx(jj-1,:)=rhor1_strain(istrpert,ii,:) 2264 end do 2265 2266 call dotprod_vn(2,rhor1_cplx,dotr,doti,nfft,nfftot,nspden,2,vqgradhart,ucvol) 2267 2268 isdq_qgradhart(re,pert_atdis(1,iatpert),pert_atdis(2,iatpert),q1grad(2,iq1grad), & 2269 & pert_strain(3,istrpert),pert_strain(4,istrpert))=dotr*half 2270 isdq_qgradhart(im,pert_atdis(1,iatpert),pert_atdis(2,iatpert),q1grad(2,iq1grad), & 2271 & pert_strain(3,istrpert),pert_strain(4,istrpert))=doti*half 2272 isdq_flg(pert_atdis(1,iatpert),pert_atdis(2,iatpert),q1grad(2,iq1grad), & 2273 & pert_strain(3,istrpert),pert_strain(4,istrpert))=1 2274 2275 blkflg(pert_atdis(2,iatpert),pert_atdis(1,iatpert), & 2276 & pert_strain(2,istrpert),pert_strain(1,istrpert), & 2277 & q1grad(2,iq1grad),matom+8)=1 2278 2279 end do 2280 end do 2281 end do 2282 end if 2283 2284 ABI_FREE(rhor1_cplx) 2285 ABI_FREE(rhog1_tmp) 2286 ABI_FREE(vqgradhart) 2287 if (nkxc == 7) then 2288 ABI_FREE(vxc1dq) 2289 ABI_SFREE(vxc1dqc) 2290 ABI_SFREE(rhor1_tmp) 2291 end if 2292 if (lw_flexo==1.or.lw_flexo==3.or.lw_flexo==4) then 2293 ABI_FREE(rhog1_atdis) 2294 ABI_FREE(rhor1_atdis) 2295 end if 2296 if (lw_flexo==1.or.lw_flexo==2) then 2297 ABI_FREE(rhog1_efield) 2298 ABI_FREE(rhor1_efield) 2299 end if 2300 if (lw_flexo==1.or.lw_flexo==2.or.lw_flexo==4) then 2301 ABI_FREE(rhor1_strain) 2302 end if 2303 2304 !################# WAVE FUNCTION CONTRIBUTIONS ####################################### 2305 2306 !Determine the subset of symmetry operations (nsym1 operations) 2307 !that leaves the perturbation invariant, and initialize corresponding arrays 2308 !symaf1, symrl1, tnons1 (and pawang1%zarot, if PAW).. 2309 !MR TODO: For the moment only the identiy symmetry is activated (nsym1=1) 2310 ! In a future I will try to activate perturbation dependent symmetries 2311 ! with littlegroup_pert.F90. 2312 nsym1 = 1 2313 ABI_MALLOC(indsy1,(4,nsym1,dtset%natom)) 2314 ABI_MALLOC(symrc1,(3,3,nsym1)) 2315 ABI_MALLOC(symaf1,(nsym1)) 2316 ABI_MALLOC(symrl1,(3,3,nsym1)) 2317 ABI_MALLOC(tnons1,(3,nsym1)) 2318 symaf1(1:nsym1)= 1 2319 symrl1(:,:,nsym1)= dtset%symrel(:,:,1) 2320 tnons1(:,nsym1)= 0_dp 2321 2322 !Set up corresponding symmetry data 2323 ABI_MALLOC(irrzon1,(dtset%nfft**(1-1/nsym1),2,(nspden/dtset%nsppol)-3*(nspden/4))) 2324 ABI_MALLOC(phnons1,(2,dtset%nfft**(1-1/nsym1),(nspden/dtset%nsppol)-3*(nspden/4))) 2325 call setsym(indsy1,irrzon1,1,dtset%natom,dtset%nfft,dtset%ngfft,nspden,dtset%nsppol,& 2326 &nsym1,phnons1,symaf1,symrc1,symrl1,tnons1,dtset%typat,xred) 2327 2328 ABI_FREE(indsy1) 2329 ABI_FREE(symaf1) 2330 ABI_FREE(symrl1) 2331 ABI_FREE(tnons1) 2332 2333 !Determine the subset of k-points needed in the "reduced Brillouin zone", 2334 !and initialize other quantities 2335 ABI_MALLOC(indkpt1_tmp,(nkpt)) 2336 ABI_MALLOC(wtk_folded,(nkpt)) 2337 ABI_MALLOC(bz2ibz_smap,(6, nkpt)) 2338 indkpt1_tmp(:)=0 2339 2340 if (dtset%kptopt==2) then 2341 call symkpt(0,gmet,indkpt1_tmp,ab_out,dtset%kptns,nkpt,nkpt_rbz,& 2342 & nsym1,symrc1,timrev,dtset%wtk,wtk_folded,bz2ibz_smap,xmpi_comm_self) 2343 else if (dtset%kptopt==3) then 2344 call symkpt(0,gmet,indkpt1_tmp,ab_out,dtset%kptns,nkpt,nkpt_rbz,& 2345 & nsym1,symrc1,0,dtset%wtk,wtk_folded,bz2ibz_smap,xmpi_comm_self) 2346 else 2347 write(msg,"(1a)") 'kptopt must be 2 or 3 for the quadrupole calculation' 2348 ABI_BUG(msg) 2349 end if 2350 ABI_FREE(bz2ibz_smap) 2351 2352 ABI_MALLOC(doccde_rbz,(dtset%mband*nkpt_rbz*dtset%nsppol)) 2353 ABI_MALLOC(indkpt1,(nkpt_rbz)) 2354 ABI_MALLOC(istwfk_rbz,(nkpt_rbz)) 2355 ABI_MALLOC(kpt_rbz,(3,nkpt_rbz)) 2356 ABI_MALLOC(nband_rbz,(nkpt_rbz*dtset%nsppol)) 2357 ABI_MALLOC(occ_rbz,(dtset%mband*nkpt_rbz*dtset%nsppol)) 2358 ABI_MALLOC(wtk_rbz,(nkpt_rbz)) 2359 indkpt1(:)=indkpt1_tmp(1:nkpt_rbz) 2360 do ikpt=1,nkpt_rbz 2361 istwfk_rbz(ikpt)=dtset%istwfk(indkpt1(ikpt)) 2362 kpt_rbz(:,ikpt)=dtset%kptns(:,indkpt1(ikpt)) 2363 wtk_rbz(ikpt)=wtk_folded(indkpt1(ikpt)) 2364 end do 2365 ABI_FREE(indkpt1_tmp) 2366 ABI_FREE(wtk_folded) 2367 2368 !Transfer occ to occ_rbz 2369 !NOTE : this takes into account that indkpt1 is ordered 2370 !MG: What about using occ(band,kpt,spin) ??? 2371 bdtot_index=0;bdtot1_index=0 2372 do isppol=1,dtset%nsppol 2373 ikpt1=1 2374 do ikpt=1,nkpt 2375 nband_k=dtset%nband(ikpt+(isppol-1)*nkpt) 2376 ! Must test against ikpt1/=nkpt_rbz+1, before evaluate indkpt1(ikpt1) 2377 if(ikpt1/=nkpt_rbz+1)then 2378 if(ikpt==indkpt1(ikpt1))then 2379 nband_rbz(ikpt1+(isppol-1)*nkpt_rbz)=nband_k 2380 occ_rbz(1+bdtot1_index:nband_k+bdtot1_index)=occ(1+bdtot_index:nband_k+bdtot_index) 2381 doccde_rbz(1+bdtot1_index:nband_k+bdtot1_index)=doccde(1+bdtot_index:nband_k+bdtot_index) 2382 ikpt1=ikpt1+1 2383 bdtot1_index=bdtot1_index+nband_k 2384 end if 2385 end if 2386 bdtot_index=bdtot_index+nband_k 2387 end do 2388 end do 2389 2390 !Compute maximum number of planewaves at k 2391 call getmpw(ecut_eff,dtset%exchn2n3d,gmet,istwfk_rbz,kpt_rbz,mpi_enreg,mpw,nkpt_rbz) 2392 2393 !Allocate some k-dependent arrays at k 2394 ABI_MALLOC(kg,(3,mpw*nkpt_rbz)) 2395 ABI_MALLOC(kg_k,(3,mpw)) 2396 ABI_MALLOC(npwarr,(nkpt_rbz)) 2397 ABI_MALLOC(npwtot,(nkpt_rbz)) 2398 2399 !Determine distribution of k-points/bands over MPI processes 2400 if (allocated(mpi_enreg%my_kpttab)) then 2401 ABI_FREE(mpi_enreg%my_kpttab) 2402 end if 2403 ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt_rbz)) 2404 if(xmpi_paral==1) then 2405 ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt_rbz,dtset%mband,dtset%nsppol)) 2406 call distrb2(dtset%mband,mband_mem,nband_rbz,nkpt_rbz,mpi_enreg%nproc_cell,dtset%nsppol,mpi_enreg) 2407 else 2408 mpi_enreg%my_kpttab(:)=(/(ii,ii=1,nkpt_rbz)/) 2409 end if 2410 my_nkpt_rbz=maxval(mpi_enreg%my_kpttab) 2411 mkmem_rbz =my_nkpt_rbz 2412 call initmpi_band(mkmem_rbz,mpi_enreg,nband_rbz,nkpt_rbz,dtset%nsppol) 2413 2414 !Set up the basis sphere of planewaves at k 2415 call kpgio(ecut_eff,dtset%exchn2n3d,gmet,istwfk_rbz,kg,& 2416 & kpt_rbz,mkmem_rbz,nband_rbz,nkpt_rbz,'PERS',mpi_enreg,mpw,npwarr,npwtot,dtset%nsppol) 2417 ABI_FREE(npwtot) 2418 2419 !Set up the spherical harmonics (Ylm) and 1st gradients at k 2420 useylmgr=1; option=2 ; nylmgr=9 2421 ABI_MALLOC(ylm,(mpw*mkmem_rbz,psps%mpsang*psps%mpsang*psps%useylm)) 2422 ABI_MALLOC(ylmgr,(mpw*mkmem_rbz,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)) 2423 if (psps%useylm==1) then 2424 call initylmg(gprimd,kg,kpt_rbz,mkmem_rbz,mpi_enreg,psps%mpsang,mpw,nband_rbz,nkpt_rbz,& 2425 & npwarr,dtset%nsppol,option,rprimd,ylm,ylmgr) 2426 end if 2427 2428 !Initialize band structure datatype at k 2429 bantot_rbz=sum(nband_rbz(1:nkpt_rbz*dtset%nsppol)) 2430 ABI_MALLOC(eigen0,(bantot_rbz)) 2431 eigen0(:)=zero 2432 ! CP modified 2433 ! call ebands_init(bantot_rbz,bs_rbz,dtset%nelect,doccde_rbz,eigen0,istwfk_rbz,kpt_rbz,& 2434 !& nband_rbz,nkpt_rbz,npwarr,dtset%nsppol,dtset%nspinor,dtset%tphysel,dtset%tsmear,dtset%occopt,occ_rbz,wtk_rbz,& 2435 !& dtset%cellcharge(1), dtset%kptopt, dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, & 2436 !& dtset%kptrlatt, dtset%nshiftk, dtset%shiftk) 2437 call ebands_init(bantot_rbz,bs_rbz,dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,& 2438 & doccde_rbz,eigen0,istwfk_rbz,kpt_rbz,nband_rbz,nkpt_rbz,npwarr,dtset%nsppol,dtset%nspinor,& 2439 & dtset%tphysel,dtset%tsmear,dtset%occopt,occ_rbz,wtk_rbz, dtset%cellcharge(1), dtset%kptopt, & 2440 & dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, dtset%kptrlatt, dtset%nshiftk, dtset%shiftk) 2441 ! End CP modified 2442 ABI_FREE(eigen0) 2443 ABI_FREE(doccde_rbz) 2444 2445 !Initialize header, update it with evolving variables 2446 gscase=0 ! A GS WF file is read 2447 call hdr_init(bs_rbz,codvsn,dtset,hdr0,pawtab,gscase,psps,wvl%descr,& 2448 & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab) 2449 2450 ! CP modified 2451 ! call hdr0%update(bantot_rbz,etotal,fermie,& 2452 !& residm,rprimd,occ_rbz,pawrhoij,xred,dtset%amu_orig(:,1),& 2453 !& comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab) 2454 call hdr0%update(bantot_rbz,etotal,fermie,fermie,& ! CP modified call to function; we assume occopt 9 does not work with DFPT 2455 & residm,rprimd,occ_rbz,pawrhoij,xred,dtset%amu_orig(:,1),& 2456 & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab) 2457 ! End CP modified 2458 2459 !Clean band structure datatype (should use it more in the future !) 2460 call ebands_free(bs_rbz) 2461 2462 !Initialize GS wavefunctions at k 2463 ireadwf0=1; formeig=0 ; ask_accurate=1 ; optorth=0 2464 mcg=mpw*dtset%nspinor*dtset%mband*mkmem_rbz*dtset%nsppol 2465 if (one*mpw*dtset%nspinor*dtset%mband*mkmem_rbz*dtset%nsppol > huge(1)) then 2466 write (msg,'(4a, 5(a,i0), 2a)')& 2467 & "Default integer is not wide enough to store the size of the GS wavefunction array (WF0, mcg).",ch10,& 2468 & "Action: increase the number of processors. Consider also OpenMP threads.",ch10,& 2469 & "nspinor: ",dtset%nspinor, "mpw: ",mpw, "mband: ",dtset%mband, "mkmem_rbz: ",& 2470 & mkmem_rbz, "nsppol: ",dtset%nsppol,ch10,& 2471 & 'Note: Compiling with large int (int64) requires a full software stack (MPI/FFTW/BLAS/LAPACK...) compiled in int64 mode' 2472 ABI_ERROR(msg) 2473 end if 2474 ABI_STAT_MALLOC(cg,(2,mcg), ierr) 2475 ABI_CHECK(ierr==0, "out-of-memory in cg") 2476 2477 ABI_MALLOC(eigen0,(dtset%mband*nkpt_rbz*dtset%nsppol)) 2478 call inwffil(ask_accurate,cg,dtset,dtset%ecut,ecut_eff,eigen0,dtset%exchn2n3d,& 2479 & formeig,hdr0,ireadwf0,istwfk_rbz,kg,& 2480 & kpt_rbz,dtset%localrdwf,dtset%mband,mcg,& 2481 & mkmem_rbz,mpi_enreg,mpw,nband_rbz,dtset%ngfft,nkpt_rbz,npwarr,& 2482 & dtset%nsppol,dtset%nsym,occ_rbz,optorth,dtset%symafm,& 2483 & dtset%symrel,dtset%tnons,dtfil%unkg,wffgs,wfftgs,& 2484 & dtfil%unwffgs,dtfil%fnamewffk,wvl) 2485 ABI_FREE(eigen0) 2486 !Close wffgs%unwff, if it was ever opened (in inwffil) 2487 if (ireadwf0==1) then 2488 call WffClose(wffgs,ierr) 2489 end if 2490 2491 !==== Initialize most of the Hamiltonian ==== 2492 !1) Allocate all arrays and initialize quantities that do not depend on k and spin. 2493 !2) Perform the setup needed for the non-local factors: 2494 !3) Constant kleimann-Bylander energies are copied from psps to gs_hamkq. 2495 call init_hamiltonian(gs_hamkq,psps,pawtab,dtset%nspinor,nsppol,nspden,dtset%natom,& 2496 & dtset%typat,xred,nfft,dtset%mgfft,ngfft,rprimd,dtset%nloalg,ph1d=ph1d,& 2497 & use_gpu_cuda=dtset%use_gpu_cuda) 2498 2499 2500 !==== Initialize response functions files and handlers ==== 2501 !Atomic displacement 2502 if (lw_flexo==1.or.lw_flexo==3.or.lw_flexo==4) then 2503 ABI_MALLOC(wfk_t_atdis,(natpert)) 2504 do iatpert=1,natpert 2505 pertcase=pert_atdis(3,iatpert) 2506 call appdig(pertcase,dtfil%fnamewff1,fiwfatdis) 2507 2508 !The value 20 is taken arbitrarily I would say 2509 forunit=20+pertcase 2510 2511 !Check that atdis file exists and open it 2512 if (.not. file_exists(fiwfatdis)) then 2513 ! Trick needed to run Abinit test suite in netcdf mode. 2514 if (file_exists(nctk_ncify(fiwfatdis))) then 2515 write(msg,"(3a)")"- File: ",trim(fiwfatdis),& 2516 " does not exist but found netcdf file with similar name." 2517 call wrtout(std_out,msg,'COLL') 2518 fiwfatdis = nctk_ncify(fiwfatdis) 2519 end if 2520 if (.not. file_exists(fiwfatdis)) then 2521 ABI_ERROR('Missing file: '//TRIM(fiwfatdis)) 2522 end if 2523 end if 2524 write(msg,'(a,a)')'-open atomic displacement wf1 file :',trim(fiwfatdis) 2525 call wrtout(std_out,msg,'COLL') 2526 call wrtout(ab_out,msg,'COLL') 2527 call wfk_open_read(wfk_t_atdis(iatpert),fiwfatdis,formeig1,dtset%iomode,forunit,spaceworld) 2528 end do 2529 end if 2530 2531 !ddk files 2532 ABI_MALLOC(wfk_t_ddk,(nq1grad)) 2533 do iq1grad=1,nq1grad 2534 pertcase=q1grad(3,iq1grad) 2535 call appdig(pertcase,dtfil%fnamewffddk,fiwfddk) 2536 2537 !The value 20 is taken arbitrarily I would say 2538 forunit=20+pertcase 2539 2540 !Check that ddk file exists and open it 2541 if (.not. file_exists(fiwfddk)) then 2542 ! Trick needed to run Abinit test suite in netcdf mode. 2543 if (file_exists(nctk_ncify(fiwfddk))) then 2544 write(msg,"(3a)")"- File: ",trim(fiwfddk),& 2545 " does not exist but found netcdf file with similar name." 2546 call wrtout(std_out,msg,'COLL') 2547 fiwfddk = nctk_ncify(fiwfddk) 2548 end if 2549 if (.not. file_exists(fiwfddk)) then 2550 ABI_ERROR('Missing file: '//TRIM(fiwfddk)) 2551 end if 2552 end if 2553 write(msg, '(a,a)') '-open ddk wf1 file :',trim(fiwfddk) 2554 call wrtout(std_out,msg,'COLL') 2555 call wrtout(ab_out,msg,'COLL') 2556 call wfk_open_read(wfk_t_ddk(iq1grad),fiwfddk,formeig1,dtset%iomode,forunit,spaceworld) 2557 end do 2558 2559 !Electric field files 2560 if (lw_flexo==1.or.lw_flexo==2) then 2561 ABI_MALLOC(wfk_t_efield,(nefipert)) 2562 do iefipert=1,nefipert 2563 pertcase=pert_efield(3,iefipert) 2564 call appdig(pertcase,dtfil%fnamewff1,fiwfefield) 2565 2566 !The value 20 is taken arbitrarily I would say 2567 forunit=20+pertcase 2568 2569 !Check that efield file exists and open it 2570 if (.not. file_exists(fiwfefield)) then 2571 ! Trick needed to run Abinit test suite in netcdf mode. 2572 if (file_exists(nctk_ncify(fiwfefield))) then 2573 write(msg,"(3a)")"- File: ",trim(fiwfefield),& 2574 " does not exist but found netcdf file with similar name." 2575 call wrtout(std_out,msg,'COLL') 2576 fiwfefield = nctk_ncify(fiwfefield) 2577 end if 2578 if (.not. file_exists(fiwfefield)) then 2579 ABI_ERROR('Missing file: '//TRIM(fiwfefield)) 2580 end if 2581 end if 2582 write(msg, '(a,a)') '-open electric field wf1 file :',trim(fiwfefield) 2583 call wrtout(std_out,msg,'COLL') 2584 call wrtout(ab_out,msg,'COLL') 2585 call wfk_open_read(wfk_t_efield(iefipert),fiwfefield,formeig1,dtset%iomode,forunit,spaceworld) 2586 end do 2587 end if 2588 2589 !Strain files 2590 if (lw_flexo==1.or.lw_flexo==2.or.lw_flexo==4) then 2591 ABI_MALLOC(wfk_t_strain,(3,3)) 2592 do istrpert=1,nstrpert 2593 pertcase=pert_strain(5,istrpert) 2594 ka=pert_strain(3,istrpert) 2595 kb=pert_strain(4,istrpert) 2596 call appdig(pertcase,dtfil%fnamewff1,fiwfstrain) 2597 2598 !The value 20 is taken arbitrarily I would say 2599 forunit=20+pertcase 2600 2601 !Check that strain file exists and open it 2602 if (.not. file_exists(fiwfstrain)) then 2603 ! Trick needed to run Abinit test suite in netcdf mode. 2604 if (file_exists(nctk_ncify(fiwfstrain))) then 2605 write(msg,"(3a)")"- File: ",trim(fiwfstrain),& 2606 " does not exist but found netcdf file with similar name." 2607 call wrtout(std_out,msg,'COLL') 2608 fiwfstrain = nctk_ncify(fiwfstrain) 2609 end if 2610 if (.not. file_exists(fiwfstrain)) then 2611 ABI_ERROR('Missing file: '//TRIM(fiwfstrain)) 2612 end if 2613 end if 2614 if (ka>=kb) then 2615 write(msg, '(a,a)') '-open strain wf1 file :',trim(fiwfstrain) 2616 call wrtout(std_out,msg,'COLL') 2617 call wrtout(ab_out,msg,'COLL') 2618 call wfk_open_read(wfk_t_strain(ka,kb),fiwfstrain,formeig1,dtset%iomode,forunit,spaceworld) 2619 else 2620 wfk_t_strain(ka,kb)=wfk_t_strain(kb,ka) 2621 end if 2622 2623 end do 2624 end if 2625 2626 !d2_dkdk 2627 if (lw_flexo==1.or.lw_flexo==2) then 2628 ABI_MALLOC(wfk_t_dkdk,(nq1q2grad)) 2629 do iq1q2grad=1,nq1q2grad 2630 2631 pertcase=q1q2grad(4,iq1q2grad) 2632 call appdig(pertcase,dtfil%fnamewffdkdk,fiwfdkdk) 2633 2634 !The value 20 is taken arbitrarily I would say 2635 forunit=20+pertcase 2636 2637 !Check that d2_ddk file exists and open it 2638 if (.not. file_exists(fiwfdkdk)) then 2639 ! Trick needed to run Abinit test suite in netcdf mode. 2640 if (file_exists(nctk_ncify(fiwfdkdk))) then 2641 write(msg,"(3a)")"- File: ",trim(fiwfdkdk),& 2642 " does not exist but found netcdf file with similar name." 2643 call wrtout(std_out,msg,'COLL') 2644 fiwfdkdk = nctk_ncify(fiwfdkdk) 2645 end if 2646 if (.not. file_exists(fiwfdkdk)) then 2647 ABI_ERROR('Missing file: '//TRIM(fiwfdkdk)) 2648 end if 2649 end if 2650 if (iq1q2grad <= 6) then 2651 write(msg, '(a,a)') '-open d2_dkdk wf2 file :',trim(fiwfdkdk) 2652 call wrtout(std_out,msg,'COLL') 2653 call wrtout(ab_out,msg,'COLL') 2654 call wfk_open_read(wfk_t_dkdk(iq1q2grad),fiwfdkdk,formeig1,dtset%iomode,forunit,spaceworld) 2655 else 2656 wfk_t_dkdk(iq1q2grad)=wfk_t_dkdk(iq1q2grad-3) 2657 end if 2658 end do 2659 end if 2660 2661 !Allocate the electronic flexoelectric tensor part depending on the wave functions 2662 if (lw_flexo==1.or.lw_flexo==2) then 2663 ABI_MALLOC(elflexowf,(2,3,3,3,3)) 2664 ABI_MALLOC(elflexowf_k,(2,3,3,3,3)) 2665 ABI_MALLOC(elflexowf_t1,(2,3,3,3,3)) 2666 ABI_MALLOC(elflexowf_t1_k,(2,3,3,3,3)) 2667 ABI_MALLOC(elflexowf_t2,(2,3,3,3,3)) 2668 ABI_MALLOC(elflexowf_t2_k,(2,3,3,3,3)) 2669 ABI_MALLOC(elflexowf_t3,(2,3,3,3,3)) 2670 ABI_MALLOC(elflexowf_t3_k,(2,3,3,3,3)) 2671 ABI_MALLOC(elflexowf_t4,(2,3,3,3,3)) 2672 ABI_MALLOC(elflexowf_t4_k,(2,3,3,3,3)) 2673 ABI_MALLOC(elflexowf_t5,(2,3,3,3,3)) 2674 ABI_MALLOC(elflexowf_t5_k,(2,3,3,3,3)) 2675 elflexowf=zero 2676 elflexowf_t1=zero 2677 elflexowf_t2=zero 2678 elflexowf_t3=zero 2679 elflexowf_t4=zero 2680 elflexowf_t5=zero 2681 end if 2682 2683 !Allocate arrays for wf contributions to the first q-gradient of the dynamical matrix 2684 if (lw_flexo==1.or.lw_flexo==3) then 2685 ABI_MALLOC(ddmdqwf,(2,natpert,natpert,nq1grad)) 2686 ABI_MALLOC(ddmdqwf_k,(2,natpert,natpert,nq1grad)) 2687 ABI_MALLOC(ddmdqwf_t1,(2,natpert,natpert,nq1grad)) 2688 ABI_MALLOC(ddmdqwf_t1_k,(2,natpert,natpert,nq1grad)) 2689 ABI_MALLOC(ddmdqwf_t2,(2,natpert,natpert,nq1grad)) 2690 ABI_MALLOC(ddmdqwf_t2_k,(2,natpert,natpert,nq1grad)) 2691 ABI_MALLOC(ddmdqwf_t3,(2,natpert,natpert,nq1grad)) 2692 ABI_MALLOC(ddmdqwf_t3_k,(2,natpert,natpert,nq1grad)) 2693 ddmdqwf=zero 2694 ddmdqwf_t1=zero 2695 ddmdqwf_t2=zero 2696 ddmdqwf_t3=zero 2697 end if 2698 2699 !Allocate arrays for wf contributions to the first q-gradient of the internal strain tensor 2700 if (lw_flexo==1.or.lw_flexo==4) then 2701 ABI_MALLOC(frwfdq,(2,matom,3,3,3,nq1grad)) 2702 ABI_MALLOC(frwfdq_k,(2,matom,3,3,3,nq1grad)) 2703 ABI_MALLOC(isdqwf,(2,matom,3,nq1grad,3,3)) 2704 ABI_MALLOC(isdqwf_k,(2,matom,3,nq1grad,3,3)) 2705 ABI_MALLOC(isdqwf_t1,(2,matom,3,nq1grad,3,3)) 2706 ABI_MALLOC(isdqwf_t1_k,(2,matom,3,nq1grad,3,3)) 2707 ABI_MALLOC(isdqwf_t2,(2,matom,3,nq1grad,3,3)) 2708 ABI_MALLOC(isdqwf_t2_k,(2,matom,3,nq1grad,3,3)) 2709 ABI_MALLOC(isdqwf_t3,(2,matom,3,nq1grad,3,3)) 2710 ABI_MALLOC(isdqwf_t3_k,(2,matom,3,nq1grad,3,3)) 2711 ABI_MALLOC(isdqwf_t4,(2,matom,3,3,3,nq1grad)) 2712 ABI_MALLOC(isdqwf_t4_k,(2,matom,3,3,3,nq1grad)) 2713 ABI_MALLOC(isdqwf_t5,(2,matom,3,nq1grad,3,3)) 2714 ABI_MALLOC(isdqwf_t5_k,(2,matom,3,nq1grad,3,3)) 2715 frwfdq=zero 2716 isdqwf=zero 2717 isdqwf_t1=zero 2718 isdqwf_t2=zero 2719 isdqwf_t3=zero 2720 isdqwf_t4=zero 2721 isdqwf_t5=zero 2722 end if 2723 2724 !LOOP OVER SPINS 2725 bdtot_index=0 2726 icg=0 2727 do isppol=1,nsppol 2728 ikg=0 2729 2730 ! Continue to initialize the Hamiltonian 2731 call gs_hamkq%load_spin(isppol,with_nonlocal=.true.) 2732 2733 ! BIG FAT k POINT LOOP 2734 do ikpt=1,nkpt_rbz 2735 2736 nband_k=nband_rbz(ikpt+(isppol-1)*nkpt_rbz) 2737 istwf_k=istwfk_rbz(ikpt) 2738 npw_k=npwarr(ikpt) 2739 npw1_k=npw_k 2740 2741 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) then 2742 bdtot_index=bdtot_index+nband_k 2743 2744 cycle ! Skip the rest of the k-point loop 2745 end if 2746 2747 ABI_MALLOC(occ_k,(nband_k)) 2748 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang*psps%useylm)) 2749 ABI_MALLOC(ylmgr_k,(npw_k,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)) 2750 occ_k(:)=occ_rbz(1+bdtot_index:nband_k+bdtot_index) 2751 kpoint(:)=kpt_rbz(:,ikpt) 2752 wtk_k=wtk_rbz(ikpt) 2753 2754 ! Get plane-wave vectors and related data at k 2755 kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg) 2756 if (psps%useylm==1) then 2757 do ilm=1,psps%mpsang*psps%mpsang 2758 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 2759 end do 2760 if (useylmgr==1) then 2761 do ilm=1,psps%mpsang*psps%mpsang 2762 do ii=1,nylmgr 2763 ylmgr_k(1:npw_k,ii,ilm)=ylmgr(1+ikg:npw_k+ikg,ii,ilm) 2764 end do 2765 end do 2766 end if 2767 end if 2768 2769 ! Compute the wf contributions to the electronic flexoelectric tensor 2770 if (lw_flexo==1.or.lw_flexo==2) then 2771 call dfpt_ciflexowf(cg,cplex,dtset,elflexowf_k,elflexowf_t1_k,elflexowf_t2_k, & 2772 & elflexowf_t3_k,elflexowf_t4_k,elflexowf_t5_k, & 2773 & gs_hamkq,gsqcut,icg,ikpt,indkpt1,isppol,istwf_k, & 2774 & kg_k,kpoint,kxc,mkmem_rbz, & 2775 & mpi_enreg,mpw,nattyp,nband_k,nefipert,nfft,ngfft,nkpt_rbz,nkxc, & 2776 & npw_k,nq1grad,nq1q2grad,nspden,nsppol,nstrpert,nylmgr,occ_k, & 2777 & pert_efield,pert_strain,ph1d,psps,q1grad,q1q2grad,rhog,rhor,rmet,ucvol,useylmgr, & 2778 & vhxc1_efield,vhxc1_strain,wfk_t_efield,wfk_t_ddk, & 2779 & wfk_t_dkdk,wfk_t_strain,wtk_k,ylm_k,ylmgr_k) 2780 2781 ! Add the contribution from each k-point 2782 elflexowf=elflexowf + elflexowf_k 2783 elflexowf_t1=elflexowf_t1 + elflexowf_t1_k 2784 elflexowf_t2=elflexowf_t2 + elflexowf_t2_k 2785 elflexowf_t3=elflexowf_t3 + elflexowf_t3_k 2786 elflexowf_t4=elflexowf_t4 + elflexowf_t4_k 2787 elflexowf_t5=elflexowf_t5 + elflexowf_t5_k 2788 end if 2789 2790 ! Compute the wf contributions to the first q-gradient of the dynamical matrix 2791 if (lw_flexo==1.or.lw_flexo==3) then 2792 call dfpt_ddmdqwf(atindx,cg,cplex,ddmdqwf_k,ddmdqwf_t1_k,ddmdqwf_t2_k,ddmdqwf_t3_k,& 2793 & dtset,gs_hamkq,gsqcut,icg,ikpt,indkpt1,isppol,istwf_k,kg_k,kpoint,mkmem_rbz, & 2794 & mpi_enreg,mpw,natpert,nattyp,nband_k,nfft,ngfft,nkpt_rbz,npw_k,nq1grad,nspden, & 2795 & nsppol,nylmgr,occ_k,pert_atdis,ph1d,psps,q1grad,rmet,ucvol,useylmgr, & 2796 & vhxc1_atdis,wfk_t_atdis,wfk_t_ddk,wtk_k,xred,ylm_k,ylmgr_k) 2797 2798 ! Add the contribution from each k-point 2799 ddmdqwf=ddmdqwf + ddmdqwf_k 2800 ddmdqwf_t1=ddmdqwf_t1 + ddmdqwf_t1_k 2801 ddmdqwf_t2=ddmdqwf_t2 + ddmdqwf_t2_k 2802 ddmdqwf_t3=ddmdqwf_t3 + ddmdqwf_t3_k 2803 end if 2804 2805 ! Compute the wf contributions to the first q-gradient of the internal strain tensor 2806 if (lw_flexo==1.or.lw_flexo==4) then 2807 2808 ! First calculate the frozen wf contribution (notice the type-I indexing of 2809 ! this term) 2810 call dfpt_isdqfr(atindx,cg,dtset,frwfdq_k,gs_hamkq,gsqcut,icg,ikpt,& 2811 & isppol,istwf_k,kg_k,kpoint,mkmem_rbz,mpi_enreg,matom,mpw,natpert,nattyp,nband_k,nfft,& 2812 & ngfft,npw_k,nq1grad,nspden,nsppol,nstrpert,nylmgr,occ_k,pert_atdis, & 2813 & pert_strain,ph1d,psps,rmet,ucvol,useylmgr,wtk_k,ylm_k,ylmgr_k) 2814 2815 ! Add the contribution from each k-point 2816 frwfdq=frwfdq + frwfdq_k 2817 2818 ! Now comute the 1st order wf contributions 2819 call dfpt_isdqwf(atindx,cg,cplex,dtset,gs_hamkq,gsqcut,icg,ikpt,indkpt1,isdqwf_k, & 2820 & isdqwf_t1_k,isdqwf_t2_k,isdqwf_t3_k,isdqwf_t4_k,isdqwf_t5_k,isppol,istwf_k, & 2821 & kg_k,kpoint,kxc,matom,mkmem_rbz,mpi_enreg,mpw,natpert,nattyp,nband_k,nfft,ngfft,nkpt_rbz,nkxc, & 2822 & npw_k,nq1grad,nspden,nsppol,nstrpert,nylmgr,occ_k, & 2823 & pert_atdis,pert_strain,ph1d,psps,q1grad,rhog,rhor,rmet,ucvol,useylmgr, & 2824 & vhxc1_atdis,vhxc1_strain,wfk_t_atdis,wfk_t_ddk, & 2825 & wfk_t_strain,wtk_k,xred,ylm_k,ylmgr_k) 2826 2827 ! Add the contribution from each k-point 2828 isdqwf=isdqwf + isdqwf_k 2829 isdqwf_t1=isdqwf_t1 + isdqwf_t1_k 2830 isdqwf_t2=isdqwf_t2 + isdqwf_t2_k 2831 isdqwf_t3=isdqwf_t3 + isdqwf_t3_k 2832 isdqwf_t4=isdqwf_t4 + isdqwf_t4_k 2833 isdqwf_t5=isdqwf_t5 + isdqwf_t5_k 2834 2835 end if 2836 2837 ! Keep track of total number of bands 2838 bdtot_index=bdtot_index+nband_k 2839 2840 ! Shift arrays memory 2841 if (mkmem_rbz/=0) then 2842 icg=icg+npw_k*dtset%nspinor*nband_k 2843 ikg=ikg+npw_k 2844 end if 2845 2846 ABI_FREE(occ_k) 2847 ABI_FREE(ylm_k) 2848 ABI_FREE(ylmgr_k) 2849 2850 end do 2851 ! END BIG FAT k POINT LOOP 2852 end do 2853 !END LOOP OVER SPINS 2854 2855 !Memory cleaning 2856 call gs_hamkq%free() 2857 2858 !Close response function files 2859 if (lw_flexo==1.or.lw_flexo==3.or.lw_flexo==4) then 2860 do iatpert=1,natpert 2861 call wfk_t_atdis(iatpert)%close() 2862 end do 2863 end if 2864 if (lw_flexo==1.or.lw_flexo==2.or.lw_flexo==4) then 2865 do istrpert=1,nstrpert 2866 if (istrpert <= 6) then 2867 ka=pert_strain(3,istrpert) 2868 kb=pert_strain(4,istrpert) 2869 call wfk_t_strain(ka,kb)%close() 2870 end if 2871 end do 2872 end if 2873 do iq1grad=1,nq1grad 2874 call wfk_t_ddk(iq1grad)%close() 2875 end do 2876 if (lw_flexo==1.or.lw_flexo==2) then 2877 do iefipert=1,nefipert 2878 call wfk_t_efield(iefipert)%close() 2879 end do 2880 do iq1q2grad=1,nq1q2grad 2881 if (iq1q2grad <= 6) call wfk_t_dkdk(iq1q2grad)%close() 2882 end do 2883 end if 2884 2885 !=== MPI communications ================== 2886 if (xmpi_paral==1) then 2887 2888 if (lw_flexo==1.or.lw_flexo==2) then 2889 call xmpi_sum(elflexowf,spaceworld,ierr) 2890 call xmpi_sum(elflexowf_t1,spaceworld,ierr) 2891 call xmpi_sum(elflexowf_t2,spaceworld,ierr) 2892 call xmpi_sum(elflexowf_t3,spaceworld,ierr) 2893 call xmpi_sum(elflexowf_t4,spaceworld,ierr) 2894 call xmpi_sum(elflexowf_t5,spaceworld,ierr) 2895 end if 2896 2897 if (lw_flexo==1.or.lw_flexo==3) then 2898 call xmpi_sum(ddmdqwf,spaceworld,ierr) 2899 call xmpi_sum(ddmdqwf_t1,spaceworld,ierr) 2900 call xmpi_sum(ddmdqwf_t2,spaceworld,ierr) 2901 call xmpi_sum(ddmdqwf_t3,spaceworld,ierr) 2902 end if 2903 2904 if (lw_flexo==1.or.lw_flexo==4) then 2905 call xmpi_sum(frwfdq,spaceworld,ierr) 2906 call xmpi_sum(isdqwf,spaceworld,ierr) 2907 call xmpi_sum(isdqwf_t1,spaceworld,ierr) 2908 call xmpi_sum(isdqwf_t2,spaceworld,ierr) 2909 call xmpi_sum(isdqwf_t3,spaceworld,ierr) 2910 call xmpi_sum(isdqwf_t4,spaceworld,ierr) 2911 call xmpi_sum(isdqwf_t5,spaceworld,ierr) 2912 end if 2913 2914 end if 2915 2916 !Sum the G=0 contribution to the geometric term of the first 2917 !q-gradient of the internal !strain tensor 2918 if (lw_flexo==1.or.lw_flexo==4) then 2919 fac=pi*pi 2920 2921 !LOOP OVER ATOMIC DISPLACEMENT PERTURBATIONS 2922 do iatpert=1,natpert 2923 iatom=pert_atdis(1,iatpert) 2924 iatdir=pert_atdis(2,iatpert) 2925 2926 !Determination of the atom type 2927 ia1=0 2928 itypat=0 2929 do ii=1,dtset%ntypat 2930 ia1=ia1+nattyp(ii) 2931 if(atindx(iatom)<=ia1.and.itypat==0)itypat=ii 2932 end do 2933 2934 !LOOP OVER STRAIN PERTURBATIONS 2935 do istrpert= 1, nstrpert 2936 ka=pert_strain(3,istrpert) 2937 kb=pert_strain(4,istrpert) 2938 delad=zero ; if (iatdir==kb) delad=one 2939 delbd=zero ; if (ka==kb) delbd=one 2940 2941 !LOOP OVER Q1-GRADIENT 2942 do iq1grad=1,3 2943 delag=zero ; if(iatdir==iq1grad) delag=one 2944 delbg=zero ; if(ka==iq1grad) delbg=one 2945 2946 frwfdq(1,iatom,iatdir,ka,kb,iq1grad)=frwfdq(1,iatom,iatdir,ka,kb,iq1grad)+& 2947 & fac*rhog(1,1)*psps%vlspl(1,2,itypat)*(delag*delbd+delad*delbg) 2948 2949 end do 2950 end do 2951 end do 2952 end if 2953 2954 !Anounce finalization of calculations 2955 if (lw_flexo==1.or.lw_flexo==2) then 2956 write(msg, '(a,a,a)' ) ch10, & 2957 ' Clamped-ion flexoelectric tensor calculation completed ',ch10 2958 call wrtout(std_out,msg,'COLL') 2959 call wrtout(ab_out,msg,'COLL') 2960 end if 2961 if (lw_flexo==1.or.lw_flexo==3) then 2962 write(msg, '(a,a,a)' ) ch10, & 2963 ' Dynamical matrix 1st q-gradient calculation completed ',ch10 2964 call wrtout(std_out,msg,'COLL') 2965 call wrtout(ab_out,msg,'COLL') 2966 end if 2967 if (lw_flexo==1.or.lw_flexo==4) then 2968 write(msg, '(a,a,a)' ) ch10, & 2969 ' Piezoelectric force response 1st q-gradient calculation completed ',ch10 2970 call wrtout(std_out,msg,'COLL') 2971 call wrtout(ab_out,msg,'COLL') 2972 end if 2973 2974 !Gather the different terms in the flexoelectric tensor and print them out 2975 if (me==0) then 2976 if (lw_flexo==1.or.lw_flexo==2) then 2977 call dfpt_ciflexoout(d3etot,elflexoflg,elflexowf,elflexowf_t1,elflexowf_t2, & 2978 & elflexowf_t3,elflexowf_t4,elflexowf_t5, & 2979 & elqgradhart,gprimd,dtset%kptopt,matom,mpert,nefipert, & 2980 & nstrpert,nq1grad,pert_efield,pert_strain,dtset%prtvol,q1grad,rprimd,ucvol) 2981 end if 2982 if (lw_flexo==1.or.lw_flexo==3) then 2983 call dfpt_ddmdqout(ddmdq_flg,ddmdq_qgradhart,ddmdqwf,ddmdqwf_t1,ddmdqwf_t2,ddmdqwf_t3,d3etot,& 2984 & dyewdq,gprimd,dtset%kptopt,matom,mpert,natpert,nq1grad,pert_atdis,dtset%prtvol,q1grad,rprimd) 2985 end if 2986 if (lw_flexo==1.or.lw_flexo==4) then 2987 call dfpt_isdqout(d3etot,dyewdqdq,frwfdq,gprimd,isdq_flg,isdq_qgradhart,isdqwf,isdqwf_t1,isdqwf_t2,& 2988 & isdqwf_t3,isdqwf_t4,isdqwf_t5,dtset%kptopt,matom,mpert,natpert, & 2989 & nstrpert,nq1grad,pert_atdis,pert_strain,dtset%prtvol,q1grad,rprimd,ucvol) 2990 end if 2991 end if 2992 2993 !Deallocattions 2994 if (lw_flexo==1.or.lw_flexo==3.or.lw_flexo==4) then 2995 ABI_FREE(pert_atdis) 2996 ABI_FREE(vhxc1_atdis) 2997 ABI_FREE(wfk_t_atdis) 2998 end if 2999 if (lw_flexo==1.or.lw_flexo==2) then 3000 ABI_FREE(pert_efield) 3001 ABI_FREE(q1q2grad) 3002 ABI_FREE(vhxc1_efield) 3003 ABI_FREE(elqgradhart) 3004 ABI_FREE(elflexoflg) 3005 ABI_FREE(wfk_t_efield) 3006 ABI_FREE(wfk_t_dkdk) 3007 ABI_FREE(elflexowf) 3008 ABI_FREE(elflexowf_k) 3009 ABI_FREE(elflexowf_t1) 3010 ABI_FREE(elflexowf_t1_k) 3011 ABI_FREE(elflexowf_t2) 3012 ABI_FREE(elflexowf_t2_k) 3013 ABI_FREE(elflexowf_t3) 3014 ABI_FREE(elflexowf_t3_k) 3015 ABI_FREE(elflexowf_t4) 3016 ABI_FREE(elflexowf_t4_k) 3017 ABI_FREE(elflexowf_t5) 3018 ABI_FREE(elflexowf_t5_k) 3019 end if 3020 if (lw_flexo==1.or.lw_flexo==3) then 3021 ABI_FREE(ddmdq_qgradhart) 3022 ABI_FREE(ddmdq_flg) 3023 ABI_FREE(ddmdqwf) 3024 ABI_FREE(ddmdqwf_k) 3025 ABI_FREE(ddmdqwf_t1) 3026 ABI_FREE(ddmdqwf_t1_k) 3027 ABI_FREE(ddmdqwf_t2) 3028 ABI_FREE(ddmdqwf_t2_k) 3029 ABI_FREE(ddmdqwf_t3) 3030 ABI_FREE(ddmdqwf_t3_k) 3031 end if 3032 if (lw_flexo==1.or.lw_flexo==2.or.lw_flexo==4) then 3033 ABI_FREE(pert_strain) 3034 ABI_FREE(vhxc1_strain) 3035 ABI_FREE(wfk_t_strain) 3036 end if 3037 if (lw_flexo==1.or.lw_flexo==4) then 3038 ABI_FREE(frwfdq) 3039 ABI_FREE(frwfdq_k) 3040 ABI_FREE(isdqwf) 3041 ABI_FREE(isdqwf_k) 3042 ABI_FREE(isdqwf_t1) 3043 ABI_FREE(isdqwf_t1_k) 3044 ABI_FREE(isdqwf_t2) 3045 ABI_FREE(isdqwf_t2_k) 3046 ABI_FREE(isdqwf_t3) 3047 ABI_FREE(isdqwf_t3_k) 3048 ABI_FREE(isdqwf_t4) 3049 ABI_FREE(isdqwf_t4_k) 3050 ABI_FREE(isdqwf_t5) 3051 ABI_FREE(isdqwf_t5_k) 3052 ABI_FREE(isdq_qgradhart) 3053 ABI_FREE(isdq_flg) 3054 end if 3055 ABI_FREE(cg) 3056 ABI_FREE(q1grad) 3057 ABI_FREE(ph1d) 3058 ABI_FREE(indkpt1) 3059 ABI_FREE(istwfk_rbz) 3060 ABI_FREE(kpt_rbz) 3061 ABI_FREE(nband_rbz) 3062 ABI_FREE(occ_rbz) 3063 ABI_FREE(wtk_rbz) 3064 ABI_FREE(kg) 3065 ABI_FREE(kg_k) 3066 ABI_FREE(npwarr) 3067 !ABI_FREE(mpi_enreg%my_kpttab) 3068 !ABI_FREE(mpi_enreg%proc_distrb) 3069 ABI_FREE(irrzon1) 3070 ABI_FREE(phnons1) 3071 ABI_FREE(symrc1) 3072 ABI_FREE(ylm) 3073 ABI_FREE(ylmgr) 3074 ABI_FREE(wfk_t_ddk) 3075 if(xmpi_paral==1) then 3076 ABI_FREE(mpi_enreg%proc_distrb) 3077 end if 3078 3079 ! Clean the header 3080 call hdr0%free() 3081 3082 DBG_EXIT("COLL") 3083 3084 end subroutine dfpt_flexo
ABINIT/dfpt_isdqout [ Functions ]
NAME
dfpt_isdqout
FUNCTION
This subroutine gathers the different terms entering the q-gradient of the internal strain tensor, perfofms the transformation from reduced to cartesian coordinates and writes out the tensor in output files in type-II formulation.
INPUTS
dyewdqdq(2,3,natom,3,3,3)= Second q-gradient of Ewald part of the dynamical matrix sumed over the second atomic sublattice frwfdq(2,natpert,3,3,nq1grad)=frozen wf contribution (type-I) gprimd(3,3)=reciprocal space dimensional primitive translations isdq_flg(matom,3,nq1grad,3,3)=array that indicates which elements of the q-gradient of internal strain tensor have been calculated isdq_qgradhart(2,matom,3,nq1grad,3,3)=electronic electrostatic contribution from the q-gradient of the Hartree potential isdqwf(2,matom,3,nq1grad,3,3)=total wave function contributions to the q-gradient of internal strain tensor (except t4) isdqwf_t1(2,matom,3,nq1grad,3,3)=term 1 of the wave function contribution isdqwf_t2(2,matom,3,nq1grad,3,3)=term 2 of the wave function contribution isdqwf_t3(2,matom,3,nq1grad,3,3)=term 3 of the wave function contribution isdqwf_t4(2,matom,3,3,3,nq1grad)=term 4 of the wave function contribution (type-I) isdqwf_t5(2,matom,3,nq1grad,3,3)=term 5 of the wave function contribution kptopt=2 time reversal symmetry is enforced, 3 trs is not enforced (for debugging purposes) matom=number of atoms mpert=maximum number of perturbations natpert=number of atomic displacement perturbations nstrpert=number of strain perturbations nq1grad=number of q1 (q_{\gamma}) gradients pert_atdis(3,natpert)=array with the info for the atomic displacement perturbations pert_strain(6,nstrpert)=array with the info for the strain perturbations prtvol=volume of information to be printed. 1-> The different contributions to the quadrupole are printed. q1grad(3,nq1grad)=array with the info for the q1 (q_{\gamma}) gradients rprimd(3,3)=dimensional primitive translations in real space (bohr) ucvol=Unit cell volume
OUTPUT
d3etot(2,3,mpert,3,mpert,3,mpert)= matrix of the 3DTE
SIDE EFFECTS
NOTES
SOURCE
4026 subroutine dfpt_isdqout(d3etot,dyewdqdq,frwfdq,gprimd,isdq_flg,isdq_qgradhart,isdqwf,isdqwf_t1,isdqwf_t2,& 4027 & isdqwf_t3,isdqwf_t4,isdqwf_t5,kptopt,matom,mpert,natpert, & 4028 & nstrpert,nq1grad,pert_atdis,pert_strain,prtvol,q1grad,rprimd,ucvol) 4029 4030 !Arguments ------------------------------------ 4031 !scalars 4032 integer,intent(in) :: kptopt,matom,mpert,natpert,nstrpert,nq1grad,prtvol 4033 real(dp),intent(in) :: ucvol 4034 4035 !arrays 4036 integer,intent(in) :: isdq_flg(matom,3,nq1grad,3,3) 4037 integer,intent(in) :: pert_atdis(3,natpert) 4038 integer,intent(in) :: pert_strain(6,nstrpert) 4039 integer,intent(in) :: q1grad(3,nq1grad) 4040 real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert) 4041 real(dp),intent(inout) :: dyewdqdq(2,3,matom,3,3,3) 4042 real(dp),intent(in) :: isdqwf(2,matom,3,nq1grad,3,3) 4043 real(dp),intent(inout) :: frwfdq(2,matom,3,3,3,nq1grad) 4044 real(dp),intent(inout) :: isdq_qgradhart(2,matom,3,nq1grad,3,3) 4045 real(dp),intent(inout) :: isdqwf_t1(2,matom,3,nq1grad,3,3) 4046 real(dp),intent(inout) :: isdqwf_t2(2,matom,3,nq1grad,3,3) 4047 real(dp),intent(inout) :: isdqwf_t3(2,matom,3,nq1grad,3,3) 4048 real(dp),intent(inout) :: isdqwf_t4(2,matom,3,3,3,nq1grad) 4049 real(dp),intent(inout) :: isdqwf_t5(2,matom,3,nq1grad,3,3) 4050 real(dp),intent(in) :: gprimd(3,3) 4051 real(dp),intent(in) :: rprimd(3,3) 4052 4053 !Local variables------------------------------- 4054 !scalars 4055 integer :: alpha,beta,delta,gamma 4056 integer :: iatdir,iatom,iatpert,ibuf,ii,iq1dir,iq1grad,istr1dir,istr2dir,istrpert 4057 integer :: q1pert,strcomp,strpert 4058 integer, parameter :: re=1,im=2 4059 real(dp) :: celastre,celastim,fac,tewim,tewre,tfrim,tfrre,t4im,tmpim,tmpre,t4re 4060 character(len=500) :: msg 4061 4062 !arrays 4063 integer :: flg1(3),flg2(3) 4064 integer, allocatable :: typeI_cartflag(:,:,:,:,:),redflg(:,:,:,:,:) 4065 real(dp) :: vec1(3),vec2(3) 4066 real(dp),allocatable :: dyewdqdq_cart(:,:,:,:,:,:),frwfdq_cart(:,:,:,:,:,:) 4067 real(dp),allocatable :: isdqtens_cart(:,:,:,:,:,:),isdqtens_red(:,:,:,:,:,:) 4068 real(dp),allocatable :: isdqwf_t4_cart(:,:,:,:,:,:) 4069 real(dp),allocatable :: isdqtens_buffer_cart(:,:,:,:,:,:,:) 4070 4071 ! ************************************************************************* 4072 4073 DBG_ENTER("COLL") 4074 4075 !Gather the different terms in the q-gradient of the internal strain tensor 4076 ABI_MALLOC(isdqtens_red,(2,matom,3,nq1grad,3,3)) 4077 ! isdqtens_red=zero 4078 4079 if (kptopt==3) then 4080 4081 !Compute real and 'true' imaginary parts of isdq tensor and independent 4082 !terms. The T4 term and the frozen wf contributions need further treatment 4083 !and they will be lately added to the cartesian coordinates 4084 !version of the isdq tensor 4085 do istrpert=1,nstrpert 4086 istr1dir=pert_strain(3,istrpert) 4087 istr2dir=pert_strain(4,istrpert) 4088 do iq1grad=1,nq1grad 4089 iq1dir=q1grad(2,iq1grad) 4090 do iatpert=1,natpert 4091 iatom=pert_atdis(1,iatpert) 4092 iatdir=pert_atdis(2,iatpert) 4093 4094 if (isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir)==1) then 4095 4096 !The interesting magnitude is 2 times the gradient of the second order Energy 4097 isdqtens_red(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two* & 4098 & ( isdq_qgradhart(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) + & 4099 & isdqwf(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) ) 4100 isdqtens_red(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two* & 4101 & ( isdq_qgradhart(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) + & 4102 & isdqwf(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) ) 4103 4104 !Multiply by the imaginary unit that has been factorized out 4105 tmpre=isdqtens_red(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4106 tmpim=isdqtens_red(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4107 isdqtens_red(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-tmpim 4108 isdqtens_red(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=tmpre 4109 4110 !Do the smae for the T4 term 4111 !(This is different from the flexoout routine because the factorized -i in the T4 4112 ! has to be multiplied by -2 as we did for the rest of contributions) 4113 tmpre=isdqwf_t4(re,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4114 tmpim=isdqwf_t4(im,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4115 isdqwf_t4(re,iatom,iatdir,istr1dir,istr2dir,iq1dir)=two*tmpim 4116 isdqwf_t4(im,iatom,iatdir,istr1dir,istr2dir,iq1dir)=-two*tmpre 4117 4118 !Multiply by 2 the frozen wf contribution 4119 tmpre=frwfdq(re,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4120 tmpim=frwfdq(im,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4121 frwfdq(re,iatom,iatdir,istr1dir,istr2dir,iq1dir)=two*tmpre 4122 frwfdq(im,iatom,iatdir,istr1dir,istr2dir,iq1dir)=two*tmpim 4123 4124 !Multiply by 2 the Ewald contribution 4125 tmpre=dyewdqdq(re,iatdir,iatom,istr1dir,istr2dir,iq1dir) 4126 tmpim=dyewdqdq(im,iatdir,iatom,istr1dir,istr2dir,iq1dir) 4127 dyewdqdq(re,iatdir,iatom,istr1dir,istr2dir,iq1dir)=two*tmpre 4128 dyewdqdq(im,iatdir,iatom,istr1dir,istr2dir,iq1dir)=two*tmpim 4129 4130 !Compute and save individual terms in mixed coordinates 4131 if (prtvol>=10) then 4132 4133 tmpre=isdq_qgradhart(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4134 tmpim=isdq_qgradhart(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4135 isdq_qgradhart(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4136 isdq_qgradhart(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two*tmpre 4137 4138 tmpre=isdqwf_t1(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4139 tmpim=isdqwf_t1(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4140 isdqwf_t1(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4141 isdqwf_t1(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two*tmpre 4142 4143 tmpre=isdqwf_t2(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4144 tmpim=isdqwf_t2(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4145 isdqwf_t2(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4146 isdqwf_t2(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two*tmpre 4147 4148 tmpre=isdqwf_t3(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4149 tmpim=isdqwf_t3(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4150 isdqwf_t3(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4151 isdqwf_t3(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two*tmpre 4152 4153 tmpre=isdqwf_t5(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4154 tmpim=isdqwf_t5(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4155 isdqwf_t5(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4156 isdqwf_t5(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two*tmpre 4157 4158 end if 4159 4160 end if 4161 4162 end do 4163 end do 4164 end do 4165 4166 else if (kptopt==2) then 4167 4168 !Compute real part of isdq tensor and independent 4169 !terms. The T4 term and the frozen wf contributions need further treatment 4170 !and they will be lately added to the cartesian coordinates 4171 !version of the isdq tensor 4172 do istrpert=1,nstrpert 4173 istr1dir=pert_strain(3,istrpert) 4174 istr2dir=pert_strain(4,istrpert) 4175 do iq1grad=1,nq1grad 4176 iq1dir=q1grad(2,iq1grad) 4177 do iatpert=1,natpert 4178 iatom=pert_atdis(1,iatpert) 4179 iatdir=pert_atdis(2,iatpert) 4180 4181 if (isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir)==1) then 4182 4183 !The interesting magnitude is 2 times the gradient of the second order Energy 4184 isdqtens_red(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two* & 4185 & ( isdq_qgradhart(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) + & 4186 & isdqwf(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) ) 4187 isdqtens_red(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=two* & 4188 & ( isdq_qgradhart(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) + & 4189 & isdqwf(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) ) 4190 4191 !Multiply by the imaginary unit that has been factorized out 4192 tmpre=isdqtens_red(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4193 tmpim=isdqtens_red(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4194 isdqtens_red(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-tmpim 4195 isdqtens_red(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=zero 4196 4197 !Do the smae for the T4 term 4198 !(This is different from the flexoout routine because the factorized -i in the T4 4199 ! has to be multiplied by 2 as we did for the rest of contributions) 4200 tmpre=isdqwf_t4(re,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4201 tmpim=isdqwf_t4(im,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4202 isdqwf_t4(re,iatom,iatdir,istr1dir,istr2dir,iq1dir)=two*tmpim 4203 isdqwf_t4(im,iatom,iatdir,istr1dir,istr2dir,iq1dir)=zero 4204 4205 !Multiply by 2 the frozen wf contribution 4206 tmpre=frwfdq(re,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4207 frwfdq(re,iatom,iatdir,istr1dir,istr2dir,iq1dir)=two*tmpre 4208 frwfdq(im,iatom,iatdir,istr1dir,istr2dir,iq1dir)=zero 4209 4210 !Multiply by 2 the Ewald contribution 4211 tmpre=dyewdqdq(re,iatdir,iatom,istr1dir,istr2dir,iq1dir) 4212 dyewdqdq(re,iatdir,iatom,istr1dir,istr2dir,iq1dir)=two*tmpre 4213 dyewdqdq(im,iatdir,iatom,istr1dir,istr2dir,iq1dir)=zero 4214 4215 !Compute and save individual terms in mixed coordinates 4216 if (prtvol>=10) then 4217 4218 tmpim=isdq_qgradhart(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4219 isdq_qgradhart(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4220 isdq_qgradhart(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=zero 4221 4222 tmpim=isdqwf_t1(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4223 isdqwf_t1(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4224 isdqwf_t1(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=zero 4225 4226 tmpim=isdqwf_t2(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4227 isdqwf_t2(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4228 isdqwf_t2(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=zero 4229 4230 tmpim=isdqwf_t3(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4231 isdqwf_t3(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4232 isdqwf_t3(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=zero 4233 4234 tmpim=isdqwf_t5(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4235 isdqwf_t5(re,iatom,iatdir,iq1dir,istr1dir,istr2dir)=-two*tmpim 4236 isdqwf_t5(im,iatom,iatdir,iq1dir,istr1dir,istr2dir)=zero 4237 4238 end if 4239 4240 end if 4241 4242 end do 4243 end do 4244 end do 4245 4246 else 4247 write(msg,"(1a)") 'kptopt must be 2 or 3 for long-wave DFPT calculations' 4248 ABI_BUG(msg) 4249 end if 4250 4251 !Transform to complete cartesian coordinates all the contributions 4252 ABI_MALLOC(isdqtens_cart,(2,matom,3,nq1grad,3,3)) 4253 ABI_MALLOC(isdqwf_t4_cart,(2,matom,3,3,3,nq1grad)) 4254 ABI_MALLOC(frwfdq_cart,(2,matom,3,3,3,nq1grad)) 4255 ABI_MALLOC(dyewdqdq_cart,(2,3,matom,3,3,nq1grad)) 4256 ABI_MALLOC(typeI_cartflag,(matom,3,3,3,nq1grad)) 4257 isdqtens_cart=isdqtens_red 4258 isdqwf_t4_cart=isdqwf_t4 4259 frwfdq_cart=frwfdq 4260 dyewdqdq_cart=dyewdqdq 4261 typeI_cartflag=0 4262 4263 if (prtvol>=10) then 4264 ABI_MALLOC(isdqtens_buffer_cart,(5,2,matom,3,nq1grad,3,3)) 4265 isdqtens_buffer_cart(1,:,:,:,:,:,:)=isdqwf_t1(:,:,:,:,:,:) 4266 isdqtens_buffer_cart(2,:,:,:,:,:,:)=isdqwf_t2(:,:,:,:,:,:) 4267 isdqtens_buffer_cart(3,:,:,:,:,:,:)=isdqwf_t3(:,:,:,:,:,:) 4268 isdqtens_buffer_cart(4,:,:,:,:,:,:)=isdq_qgradhart(:,:,:,:,:,:) 4269 isdqtens_buffer_cart(5,:,:,:,:,:,:)=isdqwf_t5(:,:,:,:,:,:) 4270 end if 4271 4272 !##1st transform coordinates of the atomic displacement derivative contributions 4273 do istr2dir=1,3 4274 do istr1dir=1,3 4275 do iq1dir=1,3 4276 do ii=1,2 4277 do iatom=1,matom 4278 4279 do iatdir=1,3 4280 vec1(iatdir)=isdqtens_cart(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4281 flg1(iatdir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4282 end do 4283 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 4284 do iatdir=1,3 4285 isdqtens_cart(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir)=vec2(iatdir) 4286 end do 4287 4288 do iatdir=1,3 4289 vec1(iatdir)=isdqwf_t4_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4290 flg1(iatdir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4291 end do 4292 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 4293 do iatdir=1,3 4294 isdqwf_t4_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir)=vec2(iatdir) 4295 typeI_cartflag(iatom,iatdir,istr1dir,istr2dir,iq1dir)=flg2(iatdir) 4296 end do 4297 4298 do iatdir=1,3 4299 vec1(iatdir)=frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4300 flg1(iatdir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4301 end do 4302 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 4303 do iatdir=1,3 4304 frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir)=vec2(iatdir) 4305 end do 4306 4307 do iatdir=1,3 4308 vec1(iatdir)=dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir) 4309 flg1(iatdir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4310 end do 4311 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 4312 do iatdir=1,3 4313 dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir)=vec2(iatdir) 4314 end do 4315 4316 end do 4317 end do 4318 end do 4319 end do 4320 end do 4321 4322 !For debugging, transform also all the individual contributions 4323 if (prtvol>=10) then 4324 do ibuf=1,5 4325 do istr2dir=1,3 4326 do istr1dir=1,3 4327 do iq1dir=1,3 4328 do ii=1,2 4329 do iatom=1,matom 4330 4331 do iatdir=1,3 4332 vec1(iatdir)=isdqtens_buffer_cart(ibuf,ii,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4333 flg1(iatdir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4334 end do 4335 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 4336 do iatdir=1,3 4337 isdqtens_buffer_cart(ibuf,ii,iatom,iatdir,iq1dir,istr1dir,istr2dir)=vec2(iatdir) 4338 end do 4339 4340 end do 4341 end do 4342 end do 4343 end do 4344 end do 4345 end do 4346 end if 4347 4348 !##2nd transform coordinates of the q-gradient (treat it as electric field) 4349 do istr2dir=1,3 4350 do istr1dir=1,3 4351 do iatom=1,matom 4352 do iatdir=1,3 4353 do ii=1,2 4354 4355 do iq1dir=1,3 4356 vec1(iq1dir)=isdqtens_cart(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4357 flg1(iq1dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4358 end do 4359 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 4360 do iq1dir=1,3 4361 isdqtens_cart(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir)=vec2(iq1dir) 4362 end do 4363 4364 do iq1dir=1,3 4365 vec1(iq1dir)=frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4366 flg1(iq1dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4367 end do 4368 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 4369 do iq1dir=1,3 4370 frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir)=vec2(iq1dir) 4371 end do 4372 4373 do iq1dir=1,3 4374 vec1(iq1dir)=dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir) 4375 flg1(iq1dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4376 end do 4377 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 4378 do iq1dir=1,3 4379 dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir)=vec2(iq1dir) 4380 end do 4381 4382 end do 4383 end do 4384 end do 4385 end do 4386 end do 4387 4388 !For debugging, transform also all the individual contributions 4389 if (prtvol>=10) then 4390 do ibuf=1,5 4391 do istr2dir=1,3 4392 do istr1dir=1,3 4393 do iatom=1,matom 4394 do iatdir=1,3 4395 do ii=1,2 4396 4397 do iq1dir=1,3 4398 vec1(iq1dir)=isdqtens_buffer_cart(ibuf,ii,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4399 flg1(iq1dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4400 end do 4401 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 4402 do iq1dir=1,3 4403 isdqtens_buffer_cart(ibuf,ii,iatom,iatdir,iq1dir,istr1dir,istr2dir)=vec2(iq1dir) 4404 end do 4405 4406 end do 4407 end do 4408 end do 4409 end do 4410 end do 4411 end do 4412 endif 4413 4414 !3rd## Transform the metric perturbation direction to cartesian coordinates in 4415 !the frozen wf contributions (treat it as an atomic displacement) 4416 do istr2dir=1,3 4417 do iq1dir=1,3 4418 do iatom=1,matom 4419 do iatdir=1,3 4420 do ii=1,2 4421 4422 do istr1dir=1,3 4423 vec1(istr1dir)=frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4424 flg1(istr1dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4425 end do 4426 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 4427 do istr1dir=1,3 4428 frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir)=vec2(istr1dir) 4429 end do 4430 4431 do istr1dir=1,3 4432 vec1(istr1dir)=dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir) 4433 flg1(istr1dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4434 end do 4435 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 4436 do istr1dir=1,3 4437 dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir)=vec2(istr1dir) 4438 end do 4439 4440 end do 4441 end do 4442 end do 4443 end do 4444 end do 4445 4446 !4th## Transform the second q-gradient direction to cartesian coordinates in 4447 !the frozen wf contributions (treat it as an electric field) 4448 do istr1dir=1,3 4449 do iq1dir=1,3 4450 do iatom=1,matom 4451 do iatdir=1,3 4452 do ii=1,2 4453 4454 do istr2dir=1,3 4455 vec1(istr2dir)=frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir) 4456 flg1(istr2dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4457 end do 4458 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 4459 do istr2dir=1,3 4460 frwfdq_cart(ii,iatom,iatdir,istr1dir,istr2dir,iq1dir)=vec2(istr2dir) 4461 end do 4462 4463 do istr2dir=1,3 4464 vec1(istr2dir)=dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir) 4465 flg1(istr2dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4466 end do 4467 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 4468 do istr2dir=1,3 4469 dyewdqdq_cart(ii,iatdir,iatom,istr1dir,istr2dir,iq1dir)=vec2(istr2dir) 4470 end do 4471 4472 end do 4473 end do 4474 end do 4475 end do 4476 end do 4477 4478 !Write the q-gradient fo the internal strain tensor in cartesian coordinates 4479 !Open output files 4480 if (prtvol>=10) then 4481 open(unit=71,file='isdq_wf_t1.out',status='unknown',form='formatted',action='write') 4482 open(unit=72,file='isdq_wf_t2.out',status='unknown',form='formatted',action='write') 4483 open(unit=73,file='isdq_wf_t3.out',status='unknown',form='formatted',action='write') 4484 open(unit=74,file='isdq_wf_t4.out',status='unknown',form='formatted',action='write') 4485 open(unit=75,file='isdq_wf_t5.out',status='unknown',form='formatted',action='write') 4486 open(unit=76,file='isdq_elecstic.out',status='unknown',form='formatted',action='write') 4487 open(unit=77,file='isdq_frwf.out',status='unknown',form='formatted',action='write') 4488 open(unit=78,file='isdq_ewdqdq.out',status='unknown',form='formatted',action='write') 4489 end if 4490 4491 write(ab_out,'(a)')' ' 4492 write(ab_out,'(a)')' First real-space moment of piezoelectric force-response tensor, in cartesian coordinates,' 4493 write(ab_out,'(a)')'atom atdir qgrdir strdir1 strdir2 real part imaginary part' 4494 do istr2dir=1,3 4495 delta=istr2dir 4496 do istr1dir=1,3 4497 beta=istr1dir 4498 do iq1dir=1,3 4499 gamma=iq1dir 4500 do iatom=1,matom 4501 do iatdir=1,3 4502 alpha=iatdir 4503 4504 if (typeI_cartflag(iatom,alpha,beta,delta,gamma)==1 .and. & 4505 & typeI_cartflag(iatom,alpha,delta,gamma,beta)==1 .and. & 4506 & typeI_cartflag(iatom,alpha,gamma,beta,delta)==1 ) then 4507 4508 !Converts the T4 term to type-II form 4509 t4re= isdqwf_t4_cart(re,iatom,alpha,beta,delta,gamma) + & 4510 & isdqwf_t4_cart(re,iatom,alpha,delta,gamma,beta) - & 4511 & isdqwf_t4_cart(re,iatom,alpha,gamma,beta,delta) 4512 t4im= isdqwf_t4_cart(im,iatom,alpha,beta,delta,gamma) + & 4513 & isdqwf_t4_cart(im,iatom,alpha,delta,gamma,beta) - & 4514 & isdqwf_t4_cart(im,iatom,alpha,gamma,beta,delta) 4515 4516 !Converts the frozen wf term to type-II form 4517 tfrre= frwfdq_cart(re,iatom,alpha,beta,delta,gamma) + & 4518 & frwfdq_cart(re,iatom,alpha,delta,gamma,beta) - & 4519 & frwfdq_cart(re,iatom,alpha,gamma,beta,delta) 4520 tfrim= frwfdq_cart(im,iatom,alpha,beta,delta,gamma) + & 4521 & frwfdq_cart(im,iatom,alpha,delta,gamma,beta) - & 4522 & frwfdq_cart(im,iatom,alpha,gamma,beta,delta) 4523 4524 !Converts the Ewald term to type-II form 4525 tewre= dyewdqdq_cart(re,alpha,iatom,beta,delta,gamma) + & 4526 & dyewdqdq_cart(re,alpha,iatom,delta,gamma,beta) - & 4527 & dyewdqdq_cart(re,alpha,iatom,gamma,beta,delta) 4528 4529 tewim= dyewdqdq_cart(im,alpha,iatom,beta,delta,gamma) + & 4530 & dyewdqdq_cart(im,alpha,iatom,delta,gamma,beta) - & 4531 & dyewdqdq_cart(im,alpha,iatom,gamma,beta,delta) 4532 4533 !Add the type-II T4, frozen wf and Ewald contributions 4534 isdqtens_cart(re,iatom,alpha,gamma,beta,delta)= & 4535 & isdqtens_cart(re,iatom,alpha,gamma,beta,delta) + t4re + & 4536 & half*tfrre + quarter*tewre 4537 isdqtens_cart(im,iatom,alpha,gamma,beta,delta)= & 4538 & isdqtens_cart(im,iatom,alpha,gamma,beta,delta) + t4im + & 4539 & half*tfrim + quarter*tewim 4540 4541 !Writes the complete q-gradient of internal strain tensor 4542 write(ab_out,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4543 & isdqtens_cart(re,iatom,alpha,gamma,beta,delta), & 4544 & isdqtens_cart(im,iatom,alpha,gamma,beta,delta) 4545 4546 if (prtvol>=10) then 4547 write(71,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4548 & isdqtens_buffer_cart(1,re,iatom,alpha,gamma,beta,delta), & 4549 & isdqtens_buffer_cart(1,im,iatom,alpha,gamma,beta,delta) 4550 4551 write(72,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4552 & isdqtens_buffer_cart(2,re,iatom,alpha,gamma,beta,delta), & 4553 & isdqtens_buffer_cart(2,im,iatom,alpha,gamma,beta,delta) 4554 4555 write(73,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4556 & isdqtens_buffer_cart(3,re,iatom,alpha,gamma,beta,delta), & 4557 & isdqtens_buffer_cart(3,im,iatom,alpha,gamma,beta,delta) 4558 4559 write(74,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta,t4re,t4im 4560 4561 write(75,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4562 & isdqtens_buffer_cart(5,re,iatom,alpha,gamma,beta,delta), & 4563 & isdqtens_buffer_cart(5,im,iatom,alpha,gamma,beta,delta) 4564 4565 write(76,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4566 & isdqtens_buffer_cart(4,re,iatom,alpha,gamma,beta,delta), & 4567 & isdqtens_buffer_cart(4,im,iatom,alpha,gamma,beta,delta) 4568 4569 write(77,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4570 & half*tfrre, half*tfrim 4571 4572 write(78,'(5(i5,3x),2(1x,f20.10))') iatom,alpha,gamma,beta,delta, & 4573 & quarter*tewre, quarter*tewim 4574 4575 end if 4576 4577 end if 4578 4579 end do 4580 end do 4581 write(ab_out,'(a)')' ' 4582 if (prtvol>=10) then 4583 write(71,'(a)')' ' 4584 write(72,'(a)')' ' 4585 write(73,'(a)')' ' 4586 write(74,'(a)')' ' 4587 write(75,'(a)')' ' 4588 write(76,'(a)')' ' 4589 write(77,'(a)')' ' 4590 write(78,'(a)')' ' 4591 end if 4592 end do 4593 end do 4594 end do 4595 4596 if (prtvol>=10) then 4597 close(71) 4598 close(72) 4599 close(73) 4600 close(74) 4601 close(75) 4602 close(76) 4603 close(77) 4604 close(78) 4605 end if 4606 4607 !Write the elastic tensor 4608 write(ab_out,'(a)')' ' 4609 write(ab_out,'(a)')' Clamped-ion elastic tensor, in cartesian coordinates ' 4610 write(ab_out,'(a)')' (from q-gradient of piezofrt),' 4611 write(ab_out,'(a)')' (for stressed cells it lacks an improper contribution),' 4612 write(ab_out,'(a)')' atdir qgrdir strdir1 strdir2 real part imaginary part' 4613 do istr2dir=1,3 4614 delta=istr2dir 4615 do istr1dir=1,3 4616 beta=istr1dir 4617 do iq1dir=1,3 4618 gamma=iq1dir 4619 do iatdir=1,3 4620 alpha=iatdir 4621 celastre=zero 4622 celastim=zero 4623 do iatom=1,matom 4624 4625 if (isdq_flg(iatom,alpha,gamma,beta,delta)==1) then 4626 celastre=celastre+isdqtens_cart(re,iatom,alpha,gamma,beta,delta) 4627 celastim=celastim+isdqtens_cart(im,iatom,alpha,gamma,beta,delta) 4628 end if 4629 4630 end do 4631 4632 write(ab_out,'(4(i5,4x),2(1x,f20.10))') alpha,gamma,beta,delta, & 4633 & celastre/ucvol, celastim/ucvol 4634 4635 end do 4636 end do 4637 write(ab_out,'(a)')' ' 4638 end do 4639 end do 4640 write(ab_out,'(80a)')('=',ii=1,80) 4641 4642 !Calculate the contribution to the d3etot in mixed (reduced/cartesian) coordinates 4643 isdqtens_red=isdqtens_cart 4644 ABI_FREE(isdqtens_cart) 4645 ABI_FREE(isdqwf_t4_cart) 4646 ABI_FREE(frwfdq_cart) 4647 ABI_FREE(dyewdqdq_cart) 4648 ABI_FREE(typeI_cartflag) 4649 ABI_MALLOC(redflg,(matom,3,3,3,3)) 4650 4651 !1st transform back coordinates of the atomic displacement derivative 4652 do istr2dir=1,3 4653 do istr1dir=1,3 4654 do iq1dir=1,3 4655 do ii=1,2 4656 do iatom=1,matom 4657 do iatdir=1,3 4658 vec1(iatdir)=isdqtens_red(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4659 flg1(iatdir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4660 end do 4661 call cart39(flg1,flg2,transpose(rprimd),iatom,matom,transpose(gprimd),vec1,vec2) 4662 do iatdir=1,3 4663 isdqtens_red(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir)=vec2(iatdir) 4664 redflg(iatom,iatdir,iq1dir,istr1dir,istr2dir)=flg2(iatdir) 4665 end do 4666 end do 4667 end do 4668 end do 4669 end do 4670 end do 4671 4672 !2nd transform back coordinates of the q-gradient (treat it as electric field) 4673 fac=two_pi ** 2 4674 do istr2dir=1,3 4675 do istr1dir=1,3 4676 do iatom=1,matom 4677 do iatdir=1,3 4678 do ii=1,2 4679 do iq1dir=1,3 4680 vec1(iq1dir)=isdqtens_red(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4681 flg1(iq1dir)=isdq_flg(iatom,iatdir,iq1dir,istr1dir,istr2dir) 4682 end do 4683 call cart39(flg1,flg2,transpose(rprimd),matom+2,matom,transpose(gprimd),vec1,vec2) 4684 do iq1dir=1,3 4685 isdqtens_red(ii,iatom,iatdir,iq1dir,istr1dir,istr2dir)=vec2(iq1dir)*fac 4686 redflg(iatom,iatdir,iq1dir,istr1dir,istr2dir)=flg2(iq1dir) 4687 end do 4688 end do 4689 end do 4690 end do 4691 end do 4692 end do 4693 4694 !Add contributions to d3etot (remove the -2 factor) 4695 q1pert=matom+8 4696 do istrpert=1,nstrpert 4697 strpert=pert_strain(1,istrpert) 4698 strcomp=pert_strain(2,istrpert) 4699 istr1dir=pert_strain(3,istrpert) 4700 istr2dir=pert_strain(4,istrpert) 4701 do iq1grad=1,nq1grad 4702 iq1dir=q1grad(2,iq1grad) 4703 do iatom=1,matom 4704 do iatdir=1,3 4705 4706 if (redflg(iatom,iatdir,iq1dir,istr1dir,istr2dir)==1) then 4707 d3etot(re,iatdir,iatom,strcomp,strpert,iq1dir,q1pert)= & 4708 & -half*isdqtens_red(re,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4709 d3etot(im,iatdir,iatom,strcomp,strpert,iq1dir,q1pert)= & 4710 & -half*isdqtens_red(im,iatom,iatdir,iq1dir,istr1dir,istr2dir) 4711 end if 4712 4713 end do 4714 end do 4715 end do 4716 end do 4717 4718 ABI_FREE(isdqtens_red) 4719 ABI_FREE(redflg) 4720 4721 DBG_EXIT("COLL") 4722 end subroutine dfpt_isdqout
ABINIT/dfpt_qdrpole [ Functions ]
NAME
dfpt_qdrpole
FUNCTION
This routine computes the elements of the quadrupole and the P^(1) tensor as the second order q-gradient (d2/dq1dq2) of the charge response to an atomic displacement (see, e.g., M.Royo and M. Stengel to be published). The atoms and atomic displacements directions that are evaluated are fixed by the rfatpol and rfdir variables in the input, rfdir also fixes the directions for the dq2 derivative, whereas dq1 is evaluated in all three directions.
INPUTS
atindx(natom)=index table for atoms (see gstate.f) codvsn=code version doccde(mband*nkpt*nsppol)=derivative of occupancies wrt the energy dtfil <type(datafiles_type)>=variables related to files dtset <type(dataset_type)>=all input variables for this dataset gmet(3,3)=reciprocal space metric tensor in bohr**-2. gprimd(3,3)=reciprocal space dimensional primitive translations kxc(nfft,nkxc)=exchange and correlation kernel mpert=maximum number of perturbations for output processing mpi_enreg=information about MPI parallelization nattyp(ntypat)= # atoms of each type. nfft=(effective) number of FFT grid points (for this proc) ngfft(1:18)=integer array with FFT box dimensions and other nkpt=number of k points in the full BZ nkxc=second dimension of the kxc array. If /=0, the XC kernel must be computed. nspden=number of spin-density components nsppol=1 for unpolarized, 2 for spin-polarized occ(mband*nkpt*nsppol)=occup number for each band (often 2) at each k point pawrhoij(my_natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data for the GS (DUMMY) pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data (DUMMY) pertsy(3,natom+6)=set of perturbations that form a basis for all other perturbations psps <type(pseudopotential_type)>=variables related to pseudopotentials rmet(3,3)=real space metric (bohr**2) rprimd(3,3)=dimensional primitive translations in real space (bohr) rhog(2,nfftf)=array for Fourier transform of GS electron density rhor(nfftf,nspden)=array for GS electron density in electrons/bohr**3. timrev=1 if time-reversal preserves the q wavevector; 0 otherwise. ucvol=unit cell volume in bohr**3. xred(3,natom)=reduced dimensionless atomic coordinates
OUTPUT
blkflg(3,mpert,3,mpert,3,mpert)= ( 1 if the element of the 3dte has been calculated ; 0 otherwise ) d3etot(2,3,mpert,3,mpert,3,mpert)= matrix of the 3DTE
SIDE EFFECTS
NOTES
For historical reasons the Quadrupole and P^(1) tensor has been obtained from the q-gradient of E^{\tau_{\kappa\beta}* \epsilon_{alpha}}. This is different from the equations appearing in PRX 9, 021050 (2019) which stand for the q-gradient of E^{\epsilon_{alpha}* \tau_{\kappa\beta}}. By this reason there is an additional -1 factor here when computing the physical observables.
SOURCE
138 subroutine dfpt_qdrpole(atindx,blkflg,codvsn,d3etot,doccde,dtfil,dtset,& 139 & gmet,gprimd,kxc,mpert,& 140 & mpi_enreg,nattyp,nfft,ngfft,nkpt,nkxc,& 141 & nspden,nsppol,occ,pawrhoij,pawtab,pertsy,psps,rmet,rprimd,rhog,rhor,& 142 & timrev,ucvol,xred) 143 144 !Arguments ------------------------------------ 145 !scalars 146 integer,intent(in) :: mpert,nfft,nkpt,nkxc,nspden,nsppol,timrev 147 integer,intent(inout) :: blkflg(3,mpert,3,mpert,3,mpert) 148 real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert) 149 real(dp),intent(in) :: ucvol 150 character(len=8), intent(in) :: codvsn 151 type(MPI_type),intent(inout) :: mpi_enreg 152 type(datafiles_type),intent(in) :: dtfil 153 type(dataset_type),intent(in) :: dtset 154 type(pseudopotential_type),intent(in) :: psps 155 type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw) 156 type(pawrhoij_type),intent(inout) :: pawrhoij(:) 157 !arrays 158 integer,intent(in) :: atindx(dtset%natom) 159 integer,intent(in) :: nattyp(dtset%ntypat),ngfft(18) 160 integer,intent(in) :: pertsy(3,dtset%natom+6) 161 real(dp),intent(in) :: doccde(dtset%mband*nkpt*dtset%nsppol) 162 real(dp),intent(in) :: gmet(3,3), gprimd(3,3) 163 real(dp),intent(in) :: kxc(nfft,nkxc) 164 real(dp),intent(in) :: occ(dtset%mband*nkpt*dtset%nsppol) 165 real(dp),intent(in) :: rmet(3,3),rprimd(3,3) 166 real(dp),intent(in) :: rhog(2,nfft),rhor(nfft,nspden) 167 real(dp),intent(in) :: xred(3,dtset%natom) 168 169 !Local variables------------------------------- 170 !scalars 171 integer :: ask_accurate,bdtot_index,bdtot1_index,bantot_rbz 172 integer :: cplex,formeig,forunit,gscase,iatpert,iatpert_cnt,iatpol 173 integer :: iatdir,icg,ierr,ii,ikg,ikpt,ikpt1,ilm,qcar,iq1dir,iq1grad,iq1grad_cnt 174 integer :: iq1q2grad,iq1q2grad_var,iq2dir,iq2grad,iq2grad_cnt,ireadwf0,isppol,istwf_k 175 integer :: jj,master,matom,matpert,mcg,me,mgfft 176 integer :: mkmem_rbz,mpw,my_nkpt_rbz 177 integer :: natpert,nband_k,nfftot,nhat1grdim,nkpt_rbz,npw_k,npw1_k 178 integer :: nq1grad,nq1q2grad,nq2grad,nsym1,nylmgr,n3xccc 179 integer :: optorth,optene,option,optres 180 integer :: pawread,pertcase,qdir,spaceworld 181 integer :: usexcnhat,useylmgr 182 integer :: mband_mem 183 integer,parameter :: formeig1=1 184 integer,parameter :: re=1,im=2 185 real(dp) :: boxcut,doti,dotr,dum_scl,ecut_eff,ecut,etotal,fermie,gsqcut,residm 186 real(dp) :: vres2, wtk_k 187 logical :: non_magnetic_xc 188 character(len=500) :: msg 189 character(len=fnlen) :: fi1o,fiwfatdis,fiwfefield,fiwfddk,fiwfdkdk 190 type(hdr_type) :: hdr_den 191 type(ebands_t) :: bs_rbz 192 type(hdr_type) :: hdr0 193 type(wvl_data) :: wvl 194 type(wffile_type) :: wffgs,wfftgs 195 type(gs_hamiltonian_type) :: gs_hamkq 196 197 !arrays 198 integer,allocatable :: bz2ibz_smap(:,:) 199 integer,allocatable :: indkpt1(:), indkpt1_tmp(:),indsy1(:,:,:),irrzon1(:,:,:) 200 integer,allocatable :: istwfk_rbz(:),kg(:,:),kg_k(:,:) 201 integer,allocatable :: nband_rbz(:),npwarr(:),npwtot(:) 202 integer,allocatable :: pert_atdis(:,:), pert_atdis_tmp(:,:) 203 integer,allocatable :: q1grad(:,:),q1grad_tmp(:,:),q1q2grad(:,:),q2grad(:,:),q2grad_tmp(:,:) 204 integer,allocatable :: qdrflg(:,:,:,:) 205 integer,allocatable :: symaf1(:),symrc1(:,:,:),symrl1(:,:,:) 206 real(dp) :: kpoint(3) 207 real(dp),allocatable :: cg(:,:),doccde_rbz(:) 208 real(dp),allocatable :: eigen0(:),eqgradhart(:,:,:,:) 209 real(dp),allocatable :: kpt_rbz(:,:) 210 real(dp),allocatable :: nhat(:,:),nhat1(:,:),nhat1gr(:,:,:) 211 real(dp),allocatable :: occ_k(:),occ_rbz(:) 212 real(dp),allocatable :: ph1d(:,:),phnons1(:,:,:) 213 real(dp),allocatable :: qdrpwf(:,:,:,:),qdrpwf_k(:,:,:,:) 214 real(dp),allocatable :: qdrpwf_t1(:,:,:,:),qdrpwf_t1_k(:,:,:,:) 215 real(dp),allocatable :: qdrpwf_t2(:,:,:,:),qdrpwf_t2_k(:,:,:,:) 216 real(dp),allocatable :: qdrpwf_t3(:,:,:,:),qdrpwf_t3_k(:,:,:,:) 217 real(dp),allocatable :: qdrpwf_t4(:,:,:,:),qdrpwf_t4_k(:,:,:,:) 218 real(dp),allocatable :: qdrpwf_t5(:,:,:,:),qdrpwf_t5_k(:,:,:,:) 219 real(dp),allocatable :: rhog1_atdis(:,:,:) 220 real(dp),allocatable :: rhog1_tmp(:,:) 221 real(dp),allocatable :: rhor1_atdis(:,:,:),rhor1_efield(:,:,:) 222 real(dp),allocatable :: rhor1_cplx(:,:),rhor1_tmp(:,:),rhor1_real(:,:) 223 real(dp),allocatable :: tnons1(:,:) 224 real(dp),allocatable :: vhartr1(:),vhxc1_atdis(:,:),vhxc1_efield(:,:) 225 real(dp),allocatable :: vpsp1(:),vqgradhart(:),vresid1(:,:),vxc1(:,:) 226 real(dp),allocatable :: dum_vxc(:,:),vxc1dq(:,:),vxc1dqc(:,:,:,:) 227 real(dp),allocatable :: wtk_folded(:), wtk_rbz(:) 228 real(dp),allocatable,target :: vtrial1(:,:) 229 real(dp),allocatable :: xccc3d1(:) 230 real(dp),allocatable :: ylm(:,:),ylm_k(:,:),ylmgr(:,:,:),ylmgr_k(:,:,:) 231 type(pawrhoij_type),allocatable :: pawrhoij_read(:) 232 type(wfk_t),allocatable :: wfk_t_atdis(:),wfk_t_efield(:),wfk_t_ddk(:),wfk_t_dkdk(:) 233 234 ! ************************************************************************* 235 236 DBG_ENTER("COLL") 237 238 !Anounce start of quadrupole tensor calculation 239 write(msg, '(a,80a,a,a,a)' ) ch10,('=',ii=1,80),ch10,& 240 & ' ==> Compute Quadrupole Tensor <== ',ch10 241 call wrtout(std_out,msg,'COLL') 242 call wrtout(ab_out,msg,'COLL') 243 244 !Keep track of total time spent in dfpt_qdrpole 245 !!To be implemented if required 246 247 !Init parallelism 248 spaceworld=mpi_enreg%comm_cell 249 me=mpi_enreg%me_kpt 250 master=0 251 252 !Get FFT grid(s) sizes (be careful !) See NOTES in the comments at the beginning of respfn.F90 253 mgfft=dtset%mgfft 254 ecut=dtset%ecut 255 ecut_eff=ecut*(dtset%dilatmx)**2 256 257 !Compute large sphere cut-off gsqcut 258 call getcut(boxcut,ecut,gmet,gsqcut,dtset%iboxcut,std_out,dtset%qptn,ngfft) 259 260 !Various initializations 261 cplex=2-timrev 262 matom=dtset%natom 263 usexcnhat=0 264 n3xccc=0 265 nfftot=ngfft(1)*ngfft(2)*ngfft(3) 266 non_magnetic_xc=.true. 267 268 269 !Generate the 1-dimensional phases 270 ABI_MALLOC(ph1d,(2,3*(2*dtset%mgfft+1)*dtset%natom)) 271 call getph(atindx,dtset%natom,dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3),ph1d,xred) 272 273 !################# PERTURBATIONS AND q-GRADIENTS LABELLING ############################ 274 275 !Determine which atomic displacements and q-gradient directions have to be evaluated 276 !taking into account the perturbation symmetries 277 matpert=dtset%natom*3 278 ABI_MALLOC(pert_atdis_tmp,(3,matpert)) 279 pert_atdis_tmp=0 280 iatpert_cnt=0 281 do iatpol=1,matom 282 do iatdir=1,3 283 if (pertsy(iatdir,iatpol)==1) then 284 iatpert_cnt=iatpert_cnt+1 285 pert_atdis_tmp(1,iatpert_cnt)=iatpol !atom displaced 286 pert_atdis_tmp(2,iatpert_cnt)=iatdir !direction of displacement 287 pert_atdis_tmp(3,iatpert_cnt)=(iatpol-1)*3+iatdir !like pertcase in dfpt_loopert.f90 288 end if 289 end do 290 end do 291 natpert=iatpert_cnt 292 ABI_MALLOC(pert_atdis,(3,natpert)) 293 do iatpert=1,natpert 294 pert_atdis(:,iatpert)=pert_atdis_tmp(:,iatpert) 295 end do 296 ABI_FREE(pert_atdis_tmp) 297 298 !The q2grad is related with the response to the electric field 299 ABI_MALLOC(q2grad_tmp,(3,3)) 300 q2grad_tmp=0 301 iq2grad_cnt=0 302 do iq2grad=1,3 303 if (pertsy(iq2grad,dtset%natom+2)==1) then 304 iq2grad_cnt=iq2grad_cnt+1 305 q2grad_tmp(1,iq2grad_cnt)=dtset%natom+2 !electric field pert 306 q2grad_tmp(2,iq2grad_cnt)=iq2grad !electric field direction 307 q2grad_tmp(3,iq2grad_cnt)=matpert+3+iq2grad !like pertcase in dfpt_loopert.f90 308 end if 309 end do 310 nq2grad=iq2grad_cnt 311 ABI_MALLOC(q2grad,(3,nq2grad)) 312 do iq2grad=1,nq2grad 313 q2grad(:,iq2grad)=q2grad_tmp(:,iq2grad) 314 end do 315 ABI_FREE(q2grad_tmp) 316 317 !The q1grad is related with the response to the ddk 318 ABI_MALLOC(q1grad_tmp,(3,3)) 319 q1grad_tmp=0 320 iq1grad_cnt=0 321 do iq1grad=1,3 322 if (pertsy(iq1grad,dtset%natom+1)==1) then 323 iq1grad_cnt=iq1grad_cnt+1 324 q1grad_tmp(1,iq1grad_cnt)=dtset%natom+1 !ddk perturbation 325 q1grad_tmp(2,iq1grad_cnt)=iq1grad !ddk or ddq direction 326 q1grad_tmp(3,iq1grad_cnt)=matpert+iq1grad !like pertcase in dfpt_loopert.f90 327 end if 328 end do 329 nq1grad=iq1grad_cnt 330 ABI_MALLOC(q1grad,(3,nq1grad)) 331 do iq1grad=1,nq1grad 332 q1grad(:,iq1grad)=q1grad_tmp(:,iq1grad) 333 end do 334 ABI_FREE(q1grad_tmp) 335 336 !For the evaluation of the 2nd order q-gradient, the 9 directios are activated because 337 !currently the program calculates by defect all the components of the d2_dkdk perturbation. 338 !TODO: This will have to be modified in the future when ABINIT enables to calculate specific 339 !components of the d2_dkdk 340 nq1q2grad=9 341 ABI_MALLOC(q1q2grad,(4,nq1q2grad)) 342 do iq1q2grad=1,nq1q2grad 343 call rf2_getidirs(iq1q2grad,iq1dir,iq2dir) 344 if (iq1dir==iq2dir) then 345 q1q2grad(1,iq1q2grad)=dtset%natom+10 !d2_dkdk perturbation diagonal elements 346 else 347 q1q2grad(1,iq1q2grad)=dtset%natom+11 !d2_dkdk perturbation off-diagonal elements 348 end if 349 q1q2grad(2,iq1q2grad)=iq1dir !dq1 direction 350 q1q2grad(3,iq1q2grad)=iq2dir !dq2 direction 351 iq1q2grad_var=iq1q2grad 352 if (iq1q2grad>6) iq1q2grad_var=iq1q2grad-3 !Lower=Upper diagonal triangle matrix 353 q1q2grad(4,iq1q2grad)=iq1q2grad_var+(dtset%natom+6)*3 !like pertcase in dfpt_loopert.f90 354 end do 355 356 !################# ELECTROSTATIC CONTRIBUTIONS ####################################### 357 358 !This is necessary to deactivate paw options in the dfpt_rhotov routine 359 ABI_MALLOC(pawrhoij_read,(0)) 360 pawread=0 361 nhat1grdim=0 362 ABI_MALLOC(nhat1gr,(0,0,0)) 363 ABI_MALLOC(nhat,(nfft,nspden)) 364 nhat=zero 365 ABI_MALLOC(nhat1,(cplex*nfft,nspden)) 366 nhat1=zero 367 368 !Read the electric field density response from a disk file(rhor1_efield), calculates the FFT 369 !(rhog1_tmp) and the first order Hartree and xc potentials(vhxc1_efield). 370 !TODO: In the call to read_rhor there is a security option that compares with the header 371 !hdr. Not activated at this moment. 372 ABI_MALLOC(rhog1_tmp,(2,nfft)) 373 ABI_MALLOC(rhor1_efield,(nq2grad,cplex*nfft,nspden)) 374 ABI_MALLOC(rhor1_tmp,(cplex*nfft,nspden)) 375 ABI_MALLOC(rhor1_real,(1*nfft,nspden)) 376 ABI_MALLOC(vhartr1,(cplex*nfft)) 377 ABI_MALLOC(vhxc1_efield,(nq2grad,cplex*nfft)) 378 ABI_MALLOC(vpsp1,(cplex*nfft)) 379 ABI_MALLOC(vtrial1,(cplex*nfft,nspden)) 380 ABI_MALLOC(vresid1,(cplex*nfft,nspden)) 381 ABI_MALLOC(vxc1,(cplex*nfft,nspden)) 382 ABI_MALLOC(dum_vxc,(nfft,nspden)) 383 ABI_MALLOC(xccc3d1,(cplex*n3xccc)) 384 vpsp1=zero; vtrial1=zero; dum_vxc=zero 385 optene=0; optres=1 386 do iq2grad=1,nq2grad 387 pertcase=q2grad(3,iq2grad) 388 389 !Reads a real first order density 390 call appdig(pertcase,dtfil%fildens1in,fi1o) 391 call read_rhor(fi1o, 1, nspden, nfft, ngfft, pawread, mpi_enreg, rhor1_real, & 392 & hdr_den, pawrhoij_read, spaceworld) 393 call hdr_den%free() 394 395 !Perform FFT rhor1 to rhog1 396 call fourdp(cplex,rhog1_tmp,rhor1_real,-1,mpi_enreg,nfft,1,ngfft,0) 397 398 !Accumulate density in meaningful complex arrays 399 if (timrev==0) then 400 do ii=1,nfft 401 jj=ii*2 402 rhor1_tmp(jj-1,:)=rhor1_real(ii,:) 403 rhor1_tmp(jj,:)=zero 404 end do 405 else if (timrev==1) then 406 rhor1_tmp(:,:)=rhor1_real(:,:) 407 end if 408 rhor1_efield(iq2grad,:,:)=rhor1_tmp(:,:) 409 410 !Calculate first order Hartree and xc potentials 411 call dfpt_rhotov(cplex,dum_scl,dum_scl,dum_scl,dum_scl,dum_scl, & 412 & gsqcut,q2grad(2,iq2grad),dtset%natom+2,& 413 & dtset%ixc,kxc,mpi_enreg,dtset%natom,nfft,ngfft,nhat,nhat1,nhat1gr,nhat1grdim,nkxc,& 414 & nspden,n3xccc,non_magnetic_xc,optene,optres,dtset%qptn,rhog,rhog1_tmp,rhor,rhor1_tmp,& 415 & rprimd,ucvol,psps%usepaw,usexcnhat,vhartr1,vpsp1,vresid1,vres2,vtrial1,dum_vxc,vxc1,& 416 & xccc3d1,dtset%ixcrot) 417 418 419 !Accumulate the potential in meaningful arrays 420 vhxc1_efield(iq2grad,:)=vtrial1(:,nspden) 421 422 end do 423 424 !Read the atomic displacement density response from a disk file, calculate the FFT 425 !(rhog1_atdis) and the first order Hartree and xc potentials(vhxc1_atdis). 426 ABI_MALLOC(rhog1_atdis,(natpert,2,nfft)) 427 ABI_MALLOC(rhor1_atdis,(natpert,cplex*nfft,nspden)) 428 ABI_MALLOC(vhxc1_atdis,(natpert,cplex*nfft)) 429 vtrial1=zero 430 do iatpert= 1, natpert 431 iatpol=pert_atdis(1,iatpert) 432 iatdir=pert_atdis(2,iatpert) 433 pertcase=pert_atdis(3,iatpert) 434 435 !Reads a real first order density 436 call appdig(pertcase,dtfil%fildens1in,fi1o) 437 call read_rhor(fi1o, 1, nspden, nfft, ngfft, pawread, mpi_enreg, rhor1_real, & 438 & hdr_den, pawrhoij_read, spaceworld) 439 call hdr_den%free() 440 441 !Perform FFT rhor1 to rhog1 442 call fourdp(cplex,rhog1_tmp,rhor1_real,-1,mpi_enreg,nfft,1,ngfft,0) 443 444 !Accumulate density in meaningful complex arrays 445 if (timrev==0) then 446 do ii=1,nfft 447 jj=ii*2 448 rhor1_tmp(jj-1,:)=rhor1_real(ii,:) 449 end do 450 else if (timrev==1) then 451 rhor1_tmp(:,:)=rhor1_real(:,:) 452 end if 453 rhor1_atdis(iatpert,:,:)=rhor1_tmp(:,:) 454 rhog1_atdis(iatpert,:,:)=rhog1_tmp(:,:) 455 456 !Calculate first order Hartree and xc potentials 457 call dfpt_rhotov(cplex,dum_scl,dum_scl,dum_scl,dum_scl,dum_scl, & 458 & gsqcut,iatdir,iatpol,& 459 & dtset%ixc,kxc,mpi_enreg,dtset%natom,nfft,ngfft,nhat,nhat1,nhat1gr,nhat1grdim,nkxc,& 460 & nspden,n3xccc,non_magnetic_xc,optene,optres,dtset%qptn,rhog,rhog1_tmp,rhor,rhor1_tmp,& 461 & rprimd,ucvol,psps%usepaw,usexcnhat,vhartr1,vpsp1,vresid1,vres2,vtrial1,dum_vxc,vxc1,& 462 & xccc3d1,dtset%ixcrot) 463 464 !Accumulate the potential in meaningful arrays 465 vhxc1_atdis(iatpert,:)=vtrial1(:,nspden) 466 467 end do 468 469 !These arrays will not be used anymore (for the moment) 470 ABI_FREE(rhor1_real) 471 ABI_FREE(rhor1_tmp) 472 ABI_FREE(vhartr1) 473 ABI_FREE(vpsp1) 474 ABI_FREE(vtrial1) 475 ABI_FREE(vresid1) 476 ABI_FREE(vxc1) 477 ABI_FREE(dum_vxc) 478 ABI_FREE(xccc3d1) 479 480 ABI_FREE(pawrhoij_read) 481 ABI_FREE(nhat1gr) 482 ABI_FREE(nhat) 483 ABI_FREE(nhat1) 484 485 !Calculate the electrostatic contribution from the q-gradient of the Hxc kernel 486 487 !If GGA xc first calculate the Cartesian q-gradient of the xc kernel 488 if (nkxc == 7) then 489 ABI_MALLOC(vxc1dq,(2*nfft,nspden)) 490 ABI_MALLOC(vxc1dqc,(2*nfft,nspden,natpert,3)) 491 ABI_MALLOC(rhor1_tmp,(cplex*nfft,nspden)) 492 do qcar=1,3 493 do iatpert=1,natpert 494 rhor1_tmp(:,:)=rhor1_atdis(iatpert,:,:) 495 call dfpt_mkvxcggadq(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,nkxc,nspden,qcar,rhor1_tmp,vxc1dq) 496 vxc1dqc(:,:,iatpert,qcar)=vxc1dq(:,:) 497 end do 498 end do 499 ABI_FREE(rhor1_tmp) 500 end if 501 502 ABI_MALLOC(rhor1_cplx,(2*nfft,nspden)) 503 ABI_MALLOC(vqgradhart,(2*nfft)) 504 ABI_MALLOC(eqgradhart,(2,natpert,nq2grad,nq1grad)) 505 ABI_MALLOC(qdrflg,(matom,3,3,3)) 506 qdrflg=0 507 rhor1_cplx=zero 508 do iq1grad=1,nq1grad 509 qdir=q1grad(2,iq1grad) 510 do iatpert=1,natpert 511 512 !Calculate the gradient of the Hartree potential generated by the first order atomic displacement density 513 rhog1_tmp(:,:)=rhog1_atdis(iatpert,:,:) 514 call hartredq(2,gmet,gsqcut,mpi_enreg,nfft,ngfft,qdir,rhog1_tmp,vqgradhart) 515 516 !To ckeck 517 ! call appdig(pert_atdis(3,iatpert)+q1grad(3,iq1grad),"Hartree_",fi1o) 518 ! call fftdatar_write_from_hdr("first_order_potential",fi1o,dtset%iomode,hdr_den,& 519 ! & ngfft,2,nfft,nspden,vqgradhart,mpi_enreg) 520 521 !If GGA convert the gradient of xc kernel to reduced coordinates and incorporate it to the Hartree part 522 if (nkxc == 7) then 523 vxc1dq=zero 524 do qcar=1,3 525 vxc1dq(:,:)=vxc1dq(:,:) + gprimd(qcar,qdir) * & 526 & vxc1dqc(:,:,iatpert,qcar) 527 end do 528 vqgradhart(:)=vqgradhart(:)+vxc1dq(:,1) 529 end if 530 531 do iq2grad=1,nq2grad 532 533 !Calculate the electrostatic energy term with the first order electric field density 534 !I need a cplex density for the dotprod_vn 535 do ii=1,nfft 536 jj=ii*2 537 rhor1_cplx(jj-1,:)=rhor1_efield(iq2grad,ii,:) 538 end do 539 540 call dotprod_vn(2,rhor1_cplx,dotr,doti,nfft,nfftot,nspden,2,vqgradhart,ucvol) 541 eqgradhart(re,iatpert,iq2grad,iq1grad)=dotr*half 542 eqgradhart(im,iatpert,iq2grad,iq1grad)=doti*half 543 544 qdrflg(pert_atdis(1,iatpert),pert_atdis(2,iatpert),q2grad(2,iq2grad),q1grad(2,iq1grad))=1 545 546 blkflg(q2grad(2,iq2grad),q2grad(1,iq2grad),pert_atdis(2,iatpert),pert_atdis(1,iatpert),& 547 & q1grad(2,iq1grad),matom+8)=1 548 549 end do 550 end do 551 end do 552 ABI_FREE(rhor1_cplx) 553 ABI_FREE(rhog1_tmp) 554 ABI_FREE(rhog1_atdis) 555 ABI_FREE(rhor1_atdis) 556 ABI_FREE(rhor1_efield) 557 ABI_FREE(vqgradhart) 558 if (nkxc == 7) then 559 ABI_FREE(vxc1dq) 560 ABI_FREE(vxc1dqc) 561 end if 562 563 !################# WAVE FUNCTION CONTRIBUTIONS ####################################### 564 565 !Determine the subset of symmetry operations (nsym1 operations) 566 !that leaves the perturbation invariant, and initialize corresponding arrays 567 !symaf1, symrl1, tnons1 (and pawang1%zarot, if PAW).. 568 !MR TODO: For the moment only the identiy symmetry is activated (nsym1=1) 569 ! In a future I will try to activate perturbation dependent symmetries 570 ! with littlegroup_pert.F90. 571 nsym1 = 1 572 ABI_MALLOC(indsy1,(4,nsym1,dtset%natom)) 573 ABI_MALLOC(symrc1,(3,3,nsym1)) 574 ABI_MALLOC(symaf1,(nsym1)) 575 ABI_MALLOC(symrl1,(3,3,nsym1)) 576 ABI_MALLOC(tnons1,(3,nsym1)) 577 symaf1(1:nsym1)= 1 578 symrl1(:,:,nsym1)= dtset%symrel(:,:,1) 579 tnons1(:,nsym1)= 0_dp 580 581 !Set up corresponding symmetry data 582 ABI_MALLOC(irrzon1,(dtset%nfft**(1-1/nsym1),2,(nspden/dtset%nsppol)-3*(nspden/4))) 583 ABI_MALLOC(phnons1,(2,dtset%nfft**(1-1/nsym1),(nspden/dtset%nsppol)-3*(nspden/4))) 584 call setsym(indsy1,irrzon1,1,dtset%natom,dtset%nfft,dtset%ngfft,nspden,dtset%nsppol,& 585 &nsym1,phnons1,symaf1,symrc1,symrl1,tnons1,dtset%typat,xred) 586 587 ABI_FREE(indsy1) 588 ABI_FREE(symaf1) 589 ABI_FREE(symrl1) 590 ABI_FREE(tnons1) 591 592 !Determine the subset of k-points needed in the "reduced Brillouin zone", 593 !and initialize other quantities 594 ABI_MALLOC(indkpt1_tmp,(nkpt)) 595 ABI_MALLOC(wtk_folded,(nkpt)) 596 ABI_MALLOC(bz2ibz_smap,(6, nkpt)) 597 indkpt1_tmp(:)=0 598 599 if (dtset%kptopt==2) then 600 call symkpt(0,gmet,indkpt1_tmp,ab_out,dtset%kptns,nkpt,nkpt_rbz,& 601 & nsym1,symrc1,timrev,dtset%wtk,wtk_folded,bz2ibz_smap,xmpi_comm_self) 602 else if (dtset%kptopt==3) then 603 call symkpt(0,gmet,indkpt1_tmp,ab_out,dtset%kptns,nkpt,nkpt_rbz,& 604 & nsym1,symrc1,0,dtset%wtk,wtk_folded,bz2ibz_smap,xmpi_comm_self) 605 else 606 write(msg,"(1a)") 'kptopt must be 2 or 3 for the quadrupole calculation' 607 ABI_BUG(msg) 608 end if 609 ABI_FREE(bz2ibz_smap) 610 611 ABI_MALLOC(doccde_rbz,(dtset%mband*nkpt_rbz*dtset%nsppol)) 612 ABI_MALLOC(indkpt1,(nkpt_rbz)) 613 ABI_MALLOC(istwfk_rbz,(nkpt_rbz)) 614 ABI_MALLOC(kpt_rbz,(3,nkpt_rbz)) 615 ABI_MALLOC(nband_rbz,(nkpt_rbz*dtset%nsppol)) 616 ABI_MALLOC(occ_rbz,(dtset%mband*nkpt_rbz*dtset%nsppol)) 617 ABI_MALLOC(wtk_rbz,(nkpt_rbz)) 618 indkpt1(:)=indkpt1_tmp(1:nkpt_rbz) 619 do ikpt=1,nkpt_rbz 620 istwfk_rbz(ikpt)=dtset%istwfk(indkpt1(ikpt)) 621 kpt_rbz(:,ikpt)=dtset%kptns(:,indkpt1(ikpt)) 622 wtk_rbz(ikpt)=wtk_folded(indkpt1(ikpt)) 623 end do 624 ABI_FREE(indkpt1_tmp) 625 ABI_FREE(wtk_folded) 626 627 !Transfer occ to occ_rbz 628 !NOTE : this takes into account that indkpt1 is ordered 629 !MG: What about using occ(band,kpt,spin) ??? 630 bdtot_index=0;bdtot1_index=0 631 do isppol=1,dtset%nsppol 632 ikpt1=1 633 do ikpt=1,nkpt 634 nband_k=dtset%nband(ikpt+(isppol-1)*nkpt) 635 ! Must test against ikpt1/=nkpt_rbz+1, before evaluate indkpt1(ikpt1) 636 if(ikpt1/=nkpt_rbz+1)then 637 if(ikpt==indkpt1(ikpt1))then 638 nband_rbz(ikpt1+(isppol-1)*nkpt_rbz)=nband_k 639 occ_rbz(1+bdtot1_index:nband_k+bdtot1_index)=occ(1+bdtot_index:nband_k+bdtot_index) 640 doccde_rbz(1+bdtot1_index:nband_k+bdtot1_index)=doccde(1+bdtot_index:nband_k+bdtot_index) 641 ikpt1=ikpt1+1 642 bdtot1_index=bdtot1_index+nband_k 643 end if 644 end if 645 bdtot_index=bdtot_index+nband_k 646 end do 647 end do 648 649 !Compute maximum number of planewaves at k 650 call getmpw(ecut_eff,dtset%exchn2n3d,gmet,istwfk_rbz,kpt_rbz,mpi_enreg,mpw,nkpt_rbz) 651 652 !Allocate some k-dependent arrays at k 653 ABI_MALLOC(kg,(3,mpw*nkpt_rbz)) 654 ABI_MALLOC(kg_k,(3,mpw)) 655 ABI_MALLOC(npwarr,(nkpt_rbz)) 656 ABI_MALLOC(npwtot,(nkpt_rbz)) 657 658 !Determine distribution of k-points/bands over MPI processes 659 if (allocated(mpi_enreg%my_kpttab)) then 660 ABI_FREE(mpi_enreg%my_kpttab) 661 end if 662 ABI_MALLOC(mpi_enreg%my_kpttab,(nkpt_rbz)) 663 if(xmpi_paral==1) then 664 ABI_MALLOC(mpi_enreg%proc_distrb,(nkpt_rbz,dtset%mband,dtset%nsppol)) 665 call distrb2(dtset%mband,mband_mem,nband_rbz,nkpt_rbz,mpi_enreg%nproc_cell,dtset%nsppol,mpi_enreg) 666 else 667 mpi_enreg%my_kpttab(:)=(/(ii,ii=1,nkpt_rbz)/) 668 end if 669 my_nkpt_rbz=maxval(mpi_enreg%my_kpttab) 670 mkmem_rbz =my_nkpt_rbz 671 call initmpi_band(mkmem_rbz,mpi_enreg,nband_rbz,nkpt_rbz,dtset%nsppol) 672 673 !Set up the basis sphere of planewaves at k 674 call kpgio(ecut_eff,dtset%exchn2n3d,gmet,istwfk_rbz,kg,& 675 & kpt_rbz,mkmem_rbz,nband_rbz,nkpt_rbz,'PERS',mpi_enreg,mpw,npwarr,npwtot,dtset%nsppol) 676 ABI_FREE(npwtot) 677 678 !Set up the spherical harmonics (Ylm) and 1st gradients at k 679 useylmgr=1; option=1 ; nylmgr=3 680 ABI_MALLOC(ylm,(mpw*mkmem_rbz,psps%mpsang*psps%mpsang*psps%useylm)) 681 ABI_MALLOC(ylmgr,(mpw*mkmem_rbz,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)) 682 if (psps%useylm==1) then 683 call initylmg(gprimd,kg,kpt_rbz,mkmem_rbz,mpi_enreg,psps%mpsang,mpw,nband_rbz,nkpt_rbz,& 684 & npwarr,dtset%nsppol,option,rprimd,ylm,ylmgr) 685 end if 686 687 !Initialize band structure datatype at k 688 bantot_rbz=sum(nband_rbz(1:nkpt_rbz*dtset%nsppol)) 689 ABI_MALLOC(eigen0,(bantot_rbz)) 690 eigen0(:)=zero 691 ! CP modified 692 ! call ebands_init(bantot_rbz,bs_rbz,dtset%nelect,doccde_rbz,eigen0,istwfk_rbz,kpt_rbz,& 693 !& nband_rbz,nkpt_rbz,npwarr,dtset%nsppol,dtset%nspinor,dtset%tphysel,dtset%tsmear,dtset%occopt,occ_rbz,wtk_rbz,& 694 !& dtset%cellcharge(1), dtset%kptopt, dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, & 695 !& dtset%kptrlatt, dtset%nshiftk, dtset%shiftk) 696 call ebands_init(bantot_rbz,bs_rbz,dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,& 697 & doccde_rbz,eigen0,istwfk_rbz,kpt_rbz,& 698 & nband_rbz,nkpt_rbz,npwarr,dtset%nsppol,dtset%nspinor,dtset%tphysel,dtset%tsmear,dtset%occopt,occ_rbz,wtk_rbz,& 699 & dtset%cellcharge(1), dtset%kptopt, dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, & 700 & dtset%kptrlatt, dtset%nshiftk, dtset%shiftk) 701 ! End CP modified 702 ABI_FREE(eigen0) 703 704 ABI_FREE(doccde_rbz) 705 706 !Initialize header, update it with evolving variables 707 gscase=0 ! A GS WF file is read 708 call hdr_init(bs_rbz,codvsn,dtset,hdr0,pawtab,gscase,psps,wvl%descr,& 709 & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab) 710 711 ! CP modified 712 ! call hdr0%update(bantot_rbz,etotal,fermie,& 713 !& residm,rprimd,occ_rbz,pawrhoij,xred,dtset%amu_orig(:,1),& 714 !& comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab) 715 call hdr0%update(bantot_rbz,etotal,fermie,fermie,& 716 & residm,rprimd,occ_rbz,pawrhoij,xred,dtset%amu_orig(:,1),& 717 & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab) 718 ! End CP modified 719 720 !Clean band structure datatype (should use it more in the future !) 721 call ebands_free(bs_rbz) 722 723 !!Initialize GS wavefunctions at k 724 ireadwf0=1; formeig=0 ; ask_accurate=1 ; optorth=0 725 mcg=mpw*dtset%nspinor*dtset%mband*mkmem_rbz*dtset%nsppol 726 if (one*mpw*dtset%nspinor*dtset%mband*mkmem_rbz*dtset%nsppol > huge(1)) then 727 write (msg,'(4a, 5(a,i0), 2a)')& 728 & "Default integer is not wide enough to store the size of the GS wavefunction array (WF0, mcg).",ch10,& 729 & "Action: increase the number of processors. Consider also OpenMP threads.",ch10,& 730 & "nspinor: ",dtset%nspinor, "mpw: ",mpw, "mband: ",dtset%mband, "mkmem_rbz: ",& 731 & mkmem_rbz, "nsppol: ",dtset%nsppol,ch10,& 732 & 'Note: Compiling with large int (int64) requires a full software stack (MPI/FFTW/BLAS/LAPACK...) compiled in int64 mode' 733 ABI_ERROR(msg) 734 end if 735 ABI_STAT_MALLOC(cg,(2,mcg), ierr) 736 ABI_CHECK(ierr==0, "out-of-memory in cg") 737 738 ABI_MALLOC(eigen0,(dtset%mband*nkpt_rbz*dtset%nsppol)) 739 call inwffil(ask_accurate,cg,dtset,dtset%ecut,ecut_eff,eigen0,dtset%exchn2n3d,& 740 & formeig,hdr0,ireadwf0,istwfk_rbz,kg,& 741 & kpt_rbz,dtset%localrdwf,dtset%mband,mcg,& 742 & mkmem_rbz,mpi_enreg,mpw,nband_rbz,dtset%ngfft,nkpt_rbz,npwarr,& 743 & dtset%nsppol,dtset%nsym,occ_rbz,optorth,dtset%symafm,& 744 & dtset%symrel,dtset%tnons,dtfil%unkg,wffgs,wfftgs,& 745 & dtfil%unwffgs,dtfil%fnamewffk,wvl) 746 ABI_FREE(eigen0) 747 748 !Close wffgs%unwff, if it was ever opened (in inwffil) 749 if (ireadwf0==1) then 750 call WffClose(wffgs,ierr) 751 end if 752 753 !==== Initialize most of the Hamiltonian ==== 754 !1) Allocate all arrays and initialize quantities that do not depend on k and spin. 755 !2) Perform the setup needed for the non-local factors: 756 !3) Constant kleimann-Bylander energies are copied from psps to gs_hamkq. 757 call init_hamiltonian(gs_hamkq,psps,pawtab,dtset%nspinor,nsppol,nspden,dtset%natom,& 758 & dtset%typat,xred,nfft,dtset%mgfft,ngfft,rprimd,dtset%nloalg,ph1d=ph1d,& 759 & use_gpu_cuda=dtset%use_gpu_cuda) 760 761 762 !==== Initialize response functions files and handlers ==== 763 !Atomic displacement files 764 ABI_MALLOC(wfk_t_atdis,(natpert)) 765 766 do iatpert=1,natpert 767 768 pertcase=pert_atdis(3,iatpert) 769 call appdig(pertcase,dtfil%fnamewff1,fiwfatdis) 770 771 !The value 20 is taken arbitrarily I would say 772 forunit=20+pertcase 773 774 !Check that atdis file exists and open it 775 if (.not. file_exists(fiwfatdis)) then 776 ! Trick needed to run Abinit test suite in netcdf mode. 777 if (file_exists(nctk_ncify(fiwfatdis))) then 778 write(msg,"(3a)")"- File: ",trim(fiwfatdis),& 779 " does not exist but found netcdf file with similar name." 780 call wrtout(std_out,msg,'COLL') 781 fiwfatdis = nctk_ncify(fiwfatdis) 782 end if 783 if (.not. file_exists(fiwfatdis)) then 784 ABI_ERROR('Missing file: '//TRIM(fiwfatdis)) 785 end if 786 end if 787 write(msg,'(a,a)')'-open atomic displacement wf1 file :',trim(fiwfatdis) 788 call wrtout([std_out, ab_out], msg) 789 call wfk_open_read(wfk_t_atdis(iatpert),fiwfatdis,formeig1,dtset%iomode,forunit, xmpi_comm_self) 790 end do 791 792 !ddk files 793 ABI_MALLOC(wfk_t_ddk,(nq1grad)) 794 do iq1grad=1,nq1grad 795 796 pertcase=q1grad(3,iq1grad) 797 call appdig(pertcase,dtfil%fnamewffddk,fiwfddk) 798 799 !The value 20 is taken arbitrarily I would say 800 forunit=20+pertcase 801 802 !Check that ddk file exists and open it 803 if (.not. file_exists(fiwfddk)) then 804 ! Trick needed to run Abinit test suite in netcdf mode. 805 if (file_exists(nctk_ncify(fiwfddk))) then 806 write(msg,"(3a)")"- File: ",trim(fiwfddk),& 807 " does not exist but found netcdf file with similar name." 808 call wrtout(std_out,msg,'COLL') 809 fiwfddk = nctk_ncify(fiwfddk) 810 end if 811 if (.not. file_exists(fiwfddk)) then 812 ABI_ERROR('Missing file: '//TRIM(fiwfddk)) 813 end if 814 end if 815 write(msg, '(a,a)') '-open ddk wf1 file :',trim(fiwfddk) 816 call wrtout(std_out,msg,'COLL') 817 call wrtout(ab_out,msg,'COLL') 818 call wfk_open_read(wfk_t_ddk(iq1grad),fiwfddk,formeig1,dtset%iomode,forunit,spaceworld) 819 820 end do 821 822 !Electric field files 823 ABI_MALLOC(wfk_t_efield,(nq2grad)) 824 do iq2grad=1,nq2grad 825 826 pertcase=q2grad(3,iq2grad) 827 call appdig(pertcase,dtfil%fnamewff1,fiwfefield) 828 829 !The value 20 is taken arbitrarily I would say 830 forunit=20+pertcase 831 832 !Check that efield file exists and open it 833 if (.not. file_exists(fiwfefield)) then 834 ! Trick needed to run Abinit test suite in netcdf mode. 835 if (file_exists(nctk_ncify(fiwfefield))) then 836 write(msg,"(3a)")"- File: ",trim(fiwfefield),& 837 " does not exist but found netcdf file with similar name." 838 call wrtout(std_out,msg,'COLL') 839 fiwfefield = nctk_ncify(fiwfefield) 840 end if 841 if (.not. file_exists(fiwfefield)) then 842 ABI_ERROR('Missing file: '//TRIM(fiwfefield)) 843 end if 844 end if 845 write(msg, '(a,a)') '-open electric field wf1 file :',trim(fiwfefield) 846 call wrtout(std_out,msg,'COLL') 847 call wrtout(ab_out,msg,'COLL') 848 call wfk_open_read(wfk_t_efield(iq2grad),fiwfefield,formeig1,dtset%iomode,forunit,spaceworld) 849 850 end do 851 852 !d2_dkdk 853 ABI_MALLOC(wfk_t_dkdk,(nq1q2grad)) 854 do iq1q2grad=1,nq1q2grad 855 856 pertcase=q1q2grad(4,iq1q2grad) 857 call appdig(pertcase,dtfil%fnamewffdkdk,fiwfdkdk) 858 859 !The value 20 is taken arbitrarily I would say 860 forunit=20+pertcase 861 862 !Check that d2_ddk file exists and open it 863 if (.not. file_exists(fiwfdkdk)) then 864 ! Trick needed to run Abinit test suite in netcdf mode. 865 if (file_exists(nctk_ncify(fiwfdkdk))) then 866 write(msg,"(3a)")"- File: ",trim(fiwfdkdk),& 867 " does not exist but found netcdf file with similar name." 868 call wrtout(std_out,msg,'COLL') 869 fiwfdkdk = nctk_ncify(fiwfdkdk) 870 end if 871 if (.not. file_exists(fiwfdkdk)) then 872 ABI_ERROR('Missing file: '//TRIM(fiwfdkdk)) 873 end if 874 end if 875 if (iq1q2grad <= 6) then 876 write(msg, '(a,a)') '-open d2_dkdk wf2 file :',trim(fiwfdkdk) 877 call wrtout(std_out,msg,'COLL') 878 call wrtout(ab_out,msg,'COLL') 879 call wfk_open_read(wfk_t_dkdk(iq1q2grad),fiwfdkdk,formeig1,dtset%iomode,forunit,spaceworld) 880 else 881 wfk_t_dkdk(iq1q2grad)=wfk_t_dkdk(iq1q2grad-3) 882 end if 883 884 end do 885 886 !Allocate the quadrupole tensor part depending on the wave functions 887 ABI_MALLOC(qdrpwf,(2,natpert,nq2grad,nq1grad)) 888 ABI_MALLOC(qdrpwf_k,(2,natpert,nq2grad,nq1grad)) 889 ABI_MALLOC(qdrpwf_t1,(2,natpert,nq2grad,nq1grad)) 890 ABI_MALLOC(qdrpwf_t1_k,(2,natpert,nq2grad,nq1grad)) 891 ABI_MALLOC(qdrpwf_t2,(2,natpert,nq2grad,nq1grad)) 892 ABI_MALLOC(qdrpwf_t2_k,(2,natpert,nq2grad,nq1grad)) 893 ABI_MALLOC(qdrpwf_t3,(2,natpert,nq2grad,nq1grad)) 894 ABI_MALLOC(qdrpwf_t3_k,(2,natpert,nq2grad,nq1grad)) 895 ABI_MALLOC(qdrpwf_t4,(2,natpert,nq2grad,nq1grad)) 896 ABI_MALLOC(qdrpwf_t4_k,(2,natpert,nq2grad,nq1grad)) 897 ABI_MALLOC(qdrpwf_t5,(2,natpert,nq2grad,nq1grad)) 898 ABI_MALLOC(qdrpwf_t5_k,(2,natpert,nq2grad,nq1grad)) 899 qdrpwf=zero 900 qdrpwf_t1=zero 901 qdrpwf_t2=zero 902 qdrpwf_t3=zero 903 qdrpwf_t4=zero 904 qdrpwf_t5=zero 905 906 !LOOP OVER SPINS 907 bdtot_index=0 908 icg=0 909 do isppol=1,nsppol 910 ikg=0 911 912 ! Continue to initialize the Hamiltonian 913 call gs_hamkq%load_spin(isppol,with_nonlocal=.true.) 914 915 ! BIG FAT k POINT LOOP 916 do ikpt=1,nkpt_rbz 917 918 nband_k=nband_rbz(ikpt+(isppol-1)*nkpt_rbz) 919 istwf_k=istwfk_rbz(ikpt) 920 npw_k=npwarr(ikpt) 921 npw1_k=npw_k 922 923 if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) then 924 bdtot_index=bdtot_index+nband_k 925 926 cycle ! Skip the rest of the k-point loop 927 end if 928 929 ABI_MALLOC(occ_k,(nband_k)) 930 ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang*psps%useylm)) 931 ABI_MALLOC(ylmgr_k,(npw_k,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)) 932 occ_k(:)=occ_rbz(1+bdtot_index:nband_k+bdtot_index) 933 kpoint(:)=kpt_rbz(:,ikpt) 934 wtk_k=wtk_rbz(ikpt) 935 936 ! Get plane-wave vectors and related data at k 937 kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg) 938 if (psps%useylm==1) then 939 do ilm=1,psps%mpsang*psps%mpsang 940 ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm) 941 end do 942 if (useylmgr==1) then 943 do ilm=1,psps%mpsang*psps%mpsang 944 do ii=1,nylmgr 945 ylmgr_k(1:npw_k,ii,ilm)=ylmgr(1+ikg:npw_k+ikg,ii,ilm) 946 end do 947 end do 948 end if 949 end if 950 951 call dfpt_qdrpwf(atindx,cg,cplex,dtset,gs_hamkq,gsqcut, & 952 & icg,ikpt,indkpt1,isppol,istwf_k, & 953 & kg_k,kpoint,mkmem_rbz, & 954 & mpi_enreg,mpw,natpert,nattyp,nband_k,nfft,ngfft,nkpt_rbz, & 955 & npw_k,nq1grad, & 956 & nq2grad,nq1q2grad,nspden,nsppol,nylmgr,occ_k, & 957 & pert_atdis,ph1d,psps,qdrpwf_k,qdrpwf_t1_k,qdrpwf_t2_k,qdrpwf_t3_k, & 958 & qdrpwf_t4_k,qdrpwf_t5_k,q1grad,q2grad,q1q2grad,rmet,ucvol,useylmgr, & 959 & vhxc1_atdis,vhxc1_efield,wfk_t_atdis,wfk_t_efield,wfk_t_ddk, & 960 & wfk_t_dkdk,wtk_k,xred,ylm_k,ylmgr_k) 961 962 963 ! Add the contribution from each k-point 964 qdrpwf=qdrpwf + qdrpwf_k 965 qdrpwf_t1=qdrpwf_t1 + qdrpwf_t1_k 966 qdrpwf_t2=qdrpwf_t2 + qdrpwf_t2_k 967 qdrpwf_t3=qdrpwf_t3 + qdrpwf_t3_k 968 qdrpwf_t4=qdrpwf_t4 + qdrpwf_t4_k 969 qdrpwf_t5=qdrpwf_t5 + qdrpwf_t5_k 970 971 ! Keep track of total number of bands 972 bdtot_index=bdtot_index+nband_k 973 974 ! Shift arrays memory 975 if (mkmem_rbz/=0) then 976 icg=icg+npw_k*dtset%nspinor*nband_k 977 ikg=ikg+npw_k 978 end if 979 980 ABI_FREE(occ_k) 981 ABI_FREE(ylm_k) 982 ABI_FREE(ylmgr_k) 983 984 end do 985 ! END BIG FAT k POINT LOOP 986 end do 987 !END LOOP OVER SPINS 988 989 !Memory cleaning 990 call gs_hamkq%free() 991 992 !Close response function files 993 do iatpert=1,natpert 994 call wfk_t_atdis(iatpert)%close() 995 end do 996 do iq1grad=1,nq1grad 997 call wfk_t_ddk(iq1grad)%close() 998 end do 999 do iq2grad=1,nq2grad 1000 call wfk_t_efield(iq2grad)%close() 1001 end do 1002 do iq1q2grad=1,nq1q2grad 1003 if (iq1q2grad <= 6) call wfk_t_dkdk(iq1q2grad)%close() 1004 end do 1005 1006 !=== MPI communications ================== 1007 if (xmpi_paral==1) then 1008 1009 call xmpi_sum(qdrpwf,spaceworld,ierr) 1010 call xmpi_sum(qdrpwf_t1,spaceworld,ierr) 1011 call xmpi_sum(qdrpwf_t2,spaceworld,ierr) 1012 call xmpi_sum(qdrpwf_t3,spaceworld,ierr) 1013 call xmpi_sum(qdrpwf_t4,spaceworld,ierr) 1014 call xmpi_sum(qdrpwf_t5,spaceworld,ierr) 1015 1016 end if 1017 1018 !Anounce finalization of quadrupole tensor calculation 1019 write(msg, '(a,a,a)' ) ch10, & 1020 ' Quadrupole tensor calculation completed ',ch10 1021 call wrtout(std_out,msg,'COLL') 1022 call wrtout(ab_out,msg,'COLL') 1023 1024 !Gather the different terms in the quadrupole tensor and print them out 1025 if (me==0) then 1026 call dfpt_qdrpout(d3etot,eqgradhart,gprimd,dtset%kptopt,matom,mpert,natpert,& 1027 & nq1grad,nq2grad,pert_atdis,dtset%prtvol,q1grad,q2grad,qdrflg,qdrpwf,qdrpwf_t1,qdrpwf_t2, & 1028 & qdrpwf_t3,qdrpwf_t4,qdrpwf_t5,rprimd,ucvol) 1029 end if 1030 1031 !Deallocations 1032 ABI_FREE(cg) 1033 ABI_FREE(eqgradhart) 1034 ABI_FREE(indkpt1) 1035 ABI_FREE(istwfk_rbz) 1036 ABI_FREE(kg) 1037 ABI_FREE(kg_k) 1038 ABI_FREE(kpt_rbz) 1039 ! ABI_FREE(mpi_enreg%my_kpttab) 1040 ! ABI_FREE(mpi_enreg%proc_distrb) 1041 ABI_FREE(nband_rbz) 1042 ABI_FREE(npwarr) 1043 ABI_FREE(occ_rbz) 1044 ABI_FREE(ph1d) 1045 ABI_FREE(pert_atdis) 1046 ABI_FREE(irrzon1) 1047 ABI_FREE(phnons1) 1048 ABI_FREE(qdrflg) 1049 ABI_FREE(qdrpwf) 1050 ABI_FREE(qdrpwf_k) 1051 ABI_FREE(qdrpwf_t1) 1052 ABI_FREE(qdrpwf_t2) 1053 ABI_FREE(qdrpwf_t3) 1054 ABI_FREE(qdrpwf_t4) 1055 ABI_FREE(qdrpwf_t5) 1056 ABI_FREE(qdrpwf_t1_k) 1057 ABI_FREE(qdrpwf_t2_k) 1058 ABI_FREE(qdrpwf_t3_k) 1059 ABI_FREE(qdrpwf_t4_k) 1060 ABI_FREE(qdrpwf_t5_k) 1061 ABI_FREE(q1grad) 1062 ABI_FREE(q1q2grad) 1063 ABI_FREE(q2grad) 1064 ABI_FREE(symrc1) 1065 ABI_FREE(vhxc1_atdis) 1066 ABI_FREE(vhxc1_efield) 1067 ABI_FREE(wfk_t_atdis) 1068 ABI_FREE(wfk_t_ddk) 1069 ABI_FREE(wfk_t_dkdk) 1070 ABI_FREE(wfk_t_efield) 1071 ABI_FREE(wtk_rbz) 1072 ABI_FREE(ylm) 1073 ABI_FREE(ylmgr) 1074 if(xmpi_paral==1) then 1075 ABI_FREE(mpi_enreg%proc_distrb) 1076 end if 1077 1078 ! Clean the header 1079 call hdr0%free() 1080 1081 DBG_EXIT("COLL") 1082 1083 end subroutine dfpt_qdrpole
ABINIT/dfpt_qdrpout [ Functions ]
NAME
dfpt_qdrpout
FUNCTION
This subroutine gathers the different terms entering the quadrupole tensor, perfofms the transformation from reduced to cartesian coordinates and writes out the quadrupole tensor in external files. It also writes the firts q-gradient of the polarization response to an atomic displacement.
INPUTS
eqgradhart(2,natpert,nq2grad,nq1grad)=electrostatic contribution from the q-gradient of the Hartree potential gprimd(3,3)=reciprocal space dimensional primitive translations kptopt=2 time reversal symmetry is enforced, 3 trs is not enforced (for debugging purposes) matom=maximum number of atoms to displace natpert=number of atomic displacement perturbations nq1grad=number of q1 (q_{\gamma}) gradients nq2grad=number of q2 (q_{\delta}) gradients pert_atdis(3,natpert)=array with the info for the atomic displacement perturbations prtvol=volume of information to be printed. 1-> The different contributions to the quadrupole are printed. q1grad(3,nq1grad)=array with the info for the q1 (q_{\gamma}) gradients q2grad(3,nq2grad)=array with the info for the q2 (q_{\gamma}) gradients qdrflg(matom,3,3,3)=array that indicates which quadrupole tensor elements have been calculated qdrpwf_k(2,natpert,nq2grad,nq1grad)= wave function dependent part of the quadrupole tensor for the k-point kpt qdrpwf_t1_k(2,natpert,nq2grad,nq1grad)= t1 term (see notes) of qdrpwf_k qdrpwf_t2_k(2,natpert,nq2grad,nq1grad)= t2 term (see notes) of qdrpwf_k qdrpwf_t3_k(2,natpert,nq2grad,nq1grad)= t3 term (see notes) of qdrpwf_k qdrpwf_t4_k(2,natpert,nq2grad,nq1grad)= t4 term (see notes) of qdrpwf_k qdrpwf_t5_k(2,natpert,nq2grad,nq1grad)= t5 term (see notes) of qdrpwf_k rprimd(3,3)=dimensional primitive translations in real space (bohr) ucvol=unit cell volume in bohr**3.
OUTPUT
d3etot(2,3,mpert,6,mpert,3,mpert)= matrix of the 3DTE
SIDE EFFECTS
NOTES
SOURCE
1129 subroutine dfpt_qdrpout(d3etot,eqgradhart,gprimd,kptopt,matom,mpert,natpert, & 1130 & nq1grad,nq2grad,pert_atdis,prtvol,q1grad,q2grad,qdrflg,qdrpwf,qdrpwf_t1,qdrpwf_t2, & 1131 & qdrpwf_t3,qdrpwf_t4,qdrpwf_t5,rprimd,ucvol) 1132 1133 !Arguments ------------------------------------ 1134 !scalars 1135 integer,intent(in) :: kptopt,matom,mpert,natpert,nq1grad,nq2grad,prtvol 1136 real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert) 1137 real(dp),intent(in) :: ucvol 1138 1139 !arrays 1140 integer,intent(in) :: pert_atdis(3,natpert) 1141 integer,intent(in) :: qdrflg(matom,3,3,3) 1142 integer,intent(in) :: q1grad(3,nq1grad),q2grad(3,nq2grad) 1143 real(dp),intent(in) :: eqgradhart(2,natpert,nq2grad,nq1grad) 1144 real(dp),intent(in) :: gprimd(3,3) 1145 real(dp),intent(in) :: qdrpwf(2,natpert,nq2grad,nq1grad) 1146 real(dp),intent(in) :: qdrpwf_t1(2,natpert,nq2grad,nq1grad) 1147 real(dp),intent(in) :: qdrpwf_t2(2,natpert,nq2grad,nq1grad) 1148 real(dp),intent(in) :: qdrpwf_t3(2,natpert,nq2grad,nq1grad) 1149 real(dp),intent(in) :: qdrpwf_t4(2,natpert,nq2grad,nq1grad) 1150 real(dp),intent(in) :: qdrpwf_t5(2,natpert,nq2grad,nq1grad) 1151 real(dp),intent(in) :: rprimd(3,3) 1152 1153 !Local variables------------------------------- 1154 !scalars 1155 integer :: alpha,beta,gamma 1156 integer :: iatpert,iatdir,iatom,ii,iiq1grad,iiq2grad 1157 integer :: iq1dir,iq1grad,iq2dir,iq2grad 1158 integer :: iq1pert,iq2pert 1159 integer, parameter :: re=1,im=2 1160 real(dp) :: piezore,piezoim,tmpre, tmpim 1161 character(len=500) :: msg 1162 !arrays 1163 integer :: flg1(3),flg2(3) 1164 integer,allocatable :: cartflg(:,:,:,:) 1165 real(dp) :: vec1(3),vec2(3) 1166 real(dp),allocatable :: qdrptens_cart(:,:,:,:,:),qdrptens_red(:,:,:,:,:) 1167 real(dp),allocatable :: dqpol_cart(:,:,:,:,:),dqpol_red(:,:,:,:,:) 1168 1169 ! ************************************************************************* 1170 1171 DBG_ENTER("COLL") 1172 1173 !Open output files 1174 if (prtvol>=10) then 1175 open(unit=71,file='qdrpl_wf_t1.out',status='unknown',form='formatted',action='write') 1176 open(unit=72,file='qdrpl_wf_t2.out',status='unknown',form='formatted',action='write') 1177 open(unit=73,file='qdrpl_wf_t3.out',status='unknown',form='formatted',action='write') 1178 open(unit=74,file='qdrpl_wf_t4.out',status='unknown',form='formatted',action='write') 1179 open(unit=75,file='qdrpl_wf_t5.out',status='unknown',form='formatted',action='write') 1180 open(unit=76,file='qdrpl_elecstic.out',status='unknown',form='formatted',action='write') 1181 end if 1182 1183 !Gather the different terms in the tensors and print the result 1184 ABI_MALLOC(qdrptens_red,(2,matom,3,3,3)) 1185 ABI_MALLOC(dqpol_red,(2,matom,3,3,3)) 1186 1187 if (kptopt==3) then 1188 1189 !Write real and 'true' imaginary parts of quadrupole tensor and the 1190 !q-gradient of the polarization response 1191 iq1pert=matom+8 1192 iq2pert=matom+2 1193 do iq1grad=1,nq1grad 1194 iq1dir=q1grad(2,iq1grad) 1195 do iq2grad=1,nq2grad 1196 iq2dir=q2grad(2,iq2grad) 1197 do iatpert=1,natpert 1198 iatom=pert_atdis(1,iatpert) 1199 iatdir=pert_atdis(2,iatpert) 1200 1201 if (qdrflg(iatom,iatdir,iq2dir,iq1dir)==1) then 1202 1203 !Calculate and save the third order energy derivative 1204 tmpre=eqgradhart(re,iatpert,iq2grad,iq1grad)+qdrpwf(re,iatpert,iq2grad,iq1grad) 1205 tmpim=eqgradhart(im,iatpert,iq2grad,iq1grad)+qdrpwf(im,iatpert,iq2grad,iq1grad) 1206 d3etot(1,iq2dir,iq2pert,iatdir,iatom,iq1dir,iq1pert)=tmpre 1207 d3etot(2,iq2dir,iq2pert,iatdir,iatom,iq1dir,iq1pert)=tmpim 1208 1209 !Calculate and write the q-gradient of the polarization response 1210 !(without the inverse volume factor) 1211 dqpol_red(1,iatom,iatdir,iq2dir,iq1dir)=-two*tmpim 1212 dqpol_red(2,iatom,iatdir,iq2dir,iq1dir)=two*tmpre 1213 1214 if (qdrflg(iatom,iatdir,iq2dir,iq1dir)==1 .and. qdrflg(iatom,iatdir,iq1dir,iq2dir)==1 ) then 1215 1216 !Avoid double counting when summing up unsymmetrized contributions 1217 do iiq1grad=1,3 1218 if (q2grad(2,iq2grad)==q1grad(2,iiq1grad)) exit 1219 end do 1220 1221 do iiq2grad=1,3 1222 if (q1grad(2,iq1grad)==q2grad(2,iiq2grad)) exit 1223 end do 1224 1225 qdrptens_red(re,iatom,iatdir,iq2dir,iq1dir)=-two* & 1226 & ( eqgradhart(re,iatpert,iq2grad,iq1grad)+eqgradhart(re,iatpert,iiq2grad,iiq1grad) & 1227 & + qdrpwf(re,iatpert,iq2grad,iq1grad)+qdrpwf(re,iatpert,iiq2grad,iiq1grad) ) 1228 qdrptens_red(im,iatom,iatdir,iq2dir,iq1dir)=-two* & 1229 & ( eqgradhart(im,iatpert,iq2grad,iq1grad)+eqgradhart(im,iatpert,iiq2grad,iiq1grad) & 1230 & + qdrpwf(im,iatpert,iq2grad,iq1grad)+qdrpwf(im,iatpert,iiq2grad,iiq1grad) ) 1231 1232 !Divide by the imaginary unit to get the proper observable 1233 !(See M.Royo and M.Stengel paper) 1234 tmpre=qdrptens_red(re,iatom,iatdir,iq2dir,iq1dir) 1235 tmpim=qdrptens_red(im,iatom,iatdir,iq2dir,iq1dir) 1236 qdrptens_red(re,iatom,iatdir,iq2dir,iq1dir)=tmpim 1237 qdrptens_red(im,iatom,iatdir,iq2dir,iq1dir)=-tmpre 1238 1239 if (prtvol>=10) then 1240 !Write individual contributions 1241 write(71,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1242 & qdrpwf_t1(im,iatpert,iq2grad,iq1grad)+qdrpwf_t1(im,iatpert,iiq2grad,iiq1grad), & 1243 & -(qdrpwf_t1(re,iatpert,iq2grad,iq1grad)+qdrpwf_t1(re,iatpert,iiq2grad,iiq1grad)) 1244 1245 write(72,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1246 & qdrpwf_t2(im,iatpert,iq2grad,iq1grad)+qdrpwf_t2(im,iatpert,iiq2grad,iiq1grad), & 1247 & -(qdrpwf_t2(re,iatpert,iq2grad,iq1grad)+qdrpwf_t2(re,iatpert,iiq2grad,iiq1grad)) 1248 1249 write(73,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1250 & qdrpwf_t3(im,iatpert,iq2grad,iq1grad)+qdrpwf_t3(im,iatpert,iiq2grad,iiq1grad), & 1251 & -(qdrpwf_t3(re,iatpert,iq2grad,iq1grad)+qdrpwf_t3(re,iatpert,iiq2grad,iiq1grad)) 1252 1253 write(74,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1254 & qdrpwf_t4(im,iatpert,iq2grad,iq1grad)+qdrpwf_t4(im,iatpert,iiq2grad,iiq1grad), & 1255 & -(qdrpwf_t4(re,iatpert,iq2grad,iq1grad)+qdrpwf_t4(re,iatpert,iiq2grad,iiq1grad)) 1256 1257 write(75,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1258 & qdrpwf_t5(im,iatpert,iq2grad,iq1grad)+qdrpwf_t5(im,iatpert,iiq2grad,iiq1grad), & 1259 & -(qdrpwf_t5(re,iatpert,iq2grad,iq1grad)+qdrpwf_t5(re,iatpert,iiq2grad,iiq1grad)) 1260 1261 write(76,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1262 & eqgradhart(im,iatpert,iq2grad,iq1grad)+eqgradhart(im,iatpert,iiq2grad,iiq1grad), & 1263 & -(eqgradhart(re,iatpert,iq2grad,iq1grad)+eqgradhart(re,iatpert,iiq2grad,iiq1grad)) 1264 end if 1265 1266 end if 1267 end if 1268 end do 1269 end do 1270 end do 1271 1272 else if (kptopt==2) then 1273 1274 !Write real and zero imaginary parts of quadrupole tensor and the 1275 !q-gradient of the polarization response 1276 iq1pert=matom+8 1277 iq2pert=matom+2 1278 do iq1grad=1,nq1grad 1279 iq1dir=q1grad(2,iq1grad) 1280 do iq2grad=1,nq2grad 1281 iq2dir=q2grad(2,iq2grad) 1282 do iatpert=1,natpert 1283 iatom=pert_atdis(1,iatpert) 1284 iatdir=pert_atdis(2,iatpert) 1285 1286 if (qdrflg(iatom,iatdir,iq2dir,iq1dir)==1) then 1287 1288 !Calculate and save the third order energy derivative 1289 tmpim=eqgradhart(im,iatpert,iq2grad,iq1grad)+qdrpwf(im,iatpert,iq2grad,iq1grad) 1290 d3etot(1,iq2dir,iq2pert,iatdir,iatom,iq1dir,iq1pert)=zero 1291 d3etot(2,iq2dir,iq2pert,iatdir,iatom,iq1dir,iq1pert)=tmpim 1292 1293 !Calculate and write the q-gradient of the polarization response 1294 !(without the inverse volume factor) 1295 dqpol_red(1,iatom,iatdir,iq2dir,iq1dir)=-two*tmpim 1296 dqpol_red(2,iatom,iatdir,iq2dir,iq1dir)=0.0_dp 1297 1298 if (qdrflg(iatom,iatdir,iq2dir,iq1dir)==1 .and. qdrflg(iatom,iatdir,iq1dir,iq2dir)==1 ) then 1299 1300 do iiq1grad=1,3 1301 if (q2grad(2,iq2grad)==q1grad(2,iiq1grad)) exit 1302 end do 1303 1304 do iiq2grad=1,3 1305 if (q1grad(2,iq1grad)==q2grad(2,iiq2grad)) exit 1306 end do 1307 1308 qdrptens_red(re,iatom,iatdir,iq2dir,iq1dir)=-two* & 1309 & ( eqgradhart(re,iatpert,iq2grad,iq1grad)+eqgradhart(re,iatpert,iiq2grad,iiq1grad) & 1310 & + qdrpwf(re,iatpert,iq2grad,iq1grad)+qdrpwf(re,iatpert,iiq2grad,iiq1grad) ) 1311 qdrptens_red(im,iatom,iatdir,iq2dir,iq1dir)=-two* & 1312 & ( eqgradhart(im,iatpert,iq2grad,iq1grad)+eqgradhart(im,iatpert,iiq2grad,iiq1grad) & 1313 & + qdrpwf(im,iatpert,iq2grad,iq1grad)+qdrpwf(im,iatpert,iiq2grad,iiq1grad) ) 1314 1315 !Divide by the imaginary unit to get the proper observable 1316 !(See M.Royo and M.Stengel paper) 1317 tmpim=qdrptens_red(im,iatom,iatdir,iq2dir,iq1dir) 1318 qdrptens_red(re,iatom,iatdir,iq2dir,iq1dir)=tmpim 1319 qdrptens_red(im,iatom,iatdir,iq2dir,iq1dir)=0.0_dp 1320 1321 if (prtvol>=10) then 1322 !Write individual contributions 1323 write(71,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1324 & qdrpwf_t1(im,iatpert,iq2grad,iq1grad)+qdrpwf_t1(im,iatpert,iiq2grad,iiq1grad), & 1325 & 0.0_dp 1326 1327 write(72,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1328 & qdrpwf_t2(im,iatpert,iq2grad,iq1grad)+qdrpwf_t2(im,iatpert,iiq2grad,iiq1grad), & 1329 & 0.0_dp 1330 1331 write(73,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1332 & qdrpwf_t3(im,iatpert,iq2grad,iq1grad)+qdrpwf_t3(im,iatpert,iiq2grad,iiq1grad), & 1333 & 0.0_dp 1334 1335 write(74,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1336 & qdrpwf_t4(im,iatpert,iq2grad,iq1grad)+qdrpwf_t4(im,iatpert,iiq2grad,iiq1grad), & 1337 & 0.0_dp 1338 1339 write(75,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1340 & qdrpwf_t5(im,iatpert,iq2grad,iq1grad)+qdrpwf_t5(im,iatpert,iiq2grad,iiq1grad), & 1341 & 0.0_dp 1342 1343 write(76,'(4(i2,2x),2(f18.10,2x))') iq2dir,iatom,iatdir,iq1dir, & 1344 & eqgradhart(im,iatpert,iq2grad,iq1grad)+eqgradhart(im,iatpert,iiq2grad,iiq1grad), & 1345 & 0.0_dp 1346 end if 1347 1348 end if 1349 end if 1350 end do 1351 end do 1352 end do 1353 1354 else 1355 write(msg,"(1a)") 'kptopt must be 2 or 3 for the quadrupole calculation' 1356 ABI_BUG(msg) 1357 end if 1358 1359 if (prtvol>=10) then 1360 close(71) 1361 close(72) 1362 close(73) 1363 close(74) 1364 close(75) 1365 close(76) 1366 end if 1367 1368 !Transformation to cartesian coordinates of the quadrupole tensor 1369 ABI_MALLOC(qdrptens_cart,(2,matom,3,3,3)) 1370 ABI_MALLOC(dqpol_cart,(2,matom,3,3,3)) 1371 ABI_MALLOC(cartflg,(matom,3,3,3)) 1372 qdrptens_cart(:,:,:,:,:)=qdrptens_red(:,:,:,:,:) 1373 dqpol_cart(:,:,:,:,:)=dqpol_red(:,:,:,:,:) 1374 cartflg=0 1375 1376 ABI_FREE(qdrptens_red) 1377 ABI_FREE(dqpol_red) 1378 1379 !1st transform coordinates of the atomic displacement derivative 1380 do iq1dir=1,3 1381 do iq2dir=1,3 1382 do ii=1,2 1383 do iatom=1,matom 1384 1385 do iatdir=1,3 1386 vec1(iatdir)=qdrptens_cart(ii,iatom,iatdir,iq2dir,iq1dir) 1387 flg1(iatdir)=qdrflg(iatom,iatdir,iq2dir,iq1dir) 1388 end do 1389 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 1390 do iatdir=1,3 1391 qdrptens_cart(ii,iatom,iatdir,iq2dir,iq1dir)=vec2(iatdir) 1392 cartflg(iatom,iatdir,iq2dir,iq1dir)=flg2(iatdir) 1393 end do 1394 1395 do iatdir=1,3 1396 vec1(iatdir)=dqpol_cart(ii,iatom,iatdir,iq2dir,iq1dir) 1397 flg1(iatdir)=qdrflg(iatom,iatdir,iq2dir,iq1dir) 1398 end do 1399 call cart39(flg1,flg2,gprimd,iatom,matom,rprimd,vec1,vec2) 1400 do iatdir=1,3 1401 dqpol_cart(ii,iatom,iatdir,iq2dir,iq1dir)=vec2(iatdir) 1402 end do 1403 1404 end do 1405 end do 1406 end do 1407 end do 1408 1409 !2nd transform coordinates of the electric field derivative 1410 do iq1dir=1,3 1411 do iatdir=1,3 1412 do iatom=1,matom 1413 do ii=1,2 1414 do iq2dir=1,3 1415 vec1(iq2dir)=qdrptens_cart(ii,iatom,iatdir,iq2dir,iq1dir) 1416 flg1(iq2dir)=qdrflg(iatom,iatdir,iq2dir,iq1dir) 1417 end do 1418 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 1419 do iq2dir=1,3 1420 qdrptens_cart(ii,iatom,iatdir,iq2dir,iq1dir)=vec2(iq2dir) 1421 cartflg(iatom,iatdir,iq2dir,iq1dir)=flg2(iq2dir) 1422 end do 1423 1424 do iq2dir=1,3 1425 vec1(iq2dir)=dqpol_cart(ii,iatom,iatdir,iq2dir,iq1dir) 1426 flg1(iq2dir)=qdrflg(iatom,iatdir,iq2dir,iq1dir) 1427 end do 1428 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 1429 do iq2dir=1,3 1430 dqpol_cart(ii,iatom,iatdir,iq2dir,iq1dir)=vec2(iq2dir) 1431 end do 1432 1433 end do 1434 end do 1435 end do 1436 end do 1437 1438 !3rd transform coordinates of the q-gradient (treat it as electric field) 1439 do iq2dir=1,3 1440 do iatdir=1,3 1441 do iatom=1,matom 1442 do ii=1,2 1443 do iq1dir=1,3 1444 vec1(iq1dir)=qdrptens_cart(ii,iatom,iatdir,iq2dir,iq1dir) 1445 flg1(iq1dir)=qdrflg(iatom,iatdir,iq2dir,iq1dir) 1446 end do 1447 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 1448 do iq1dir=1,3 1449 qdrptens_cart(ii,iatom,iatdir,iq2dir,iq1dir)=vec2(iq1dir) 1450 cartflg(iatom,iatdir,iq2dir,iq1dir)=flg2(iq1dir) 1451 end do 1452 1453 do iq1dir=1,3 1454 vec1(iq1dir)=dqpol_cart(ii,iatom,iatdir,iq2dir,iq1dir) 1455 flg1(iq1dir)=qdrflg(iatom,iatdir,iq2dir,iq1dir) 1456 end do 1457 call cart39(flg1,flg2,gprimd,matom+2,matom,rprimd,vec1,vec2) 1458 do iq1dir=1,3 1459 dqpol_cart(ii,iatom,iatdir,iq2dir,iq1dir)=vec2(iq1dir) 1460 end do 1461 1462 end do 1463 end do 1464 end do 1465 end do 1466 1467 1468 !Write the Quadrupole tensor in cartesian coordinates 1469 write(ab_out,'(a)')' ' 1470 write(ab_out,'(a)')' Quadrupole tensor, in cartesian coordinates,' 1471 write(ab_out,'(a)')' efidir atom atddir qgrdir real part imaginary part' 1472 do iq1dir=1,3 1473 do iq2dir=1,3 1474 do iatdir=1,3 1475 do iatom=1,matom 1476 1477 if (cartflg(iatom,iatdir,iq2dir,iq1dir)==1) then 1478 1479 write(ab_out,'(4(i5,3x),2(1x,f20.10))') iq2dir,iatom,iatdir,iq1dir, & 1480 & qdrptens_cart(re,iatom,iatdir,iq2dir,iq1dir),qdrptens_cart(im,iatom,iatdir,iq2dir,iq1dir) 1481 1482 end if 1483 1484 end do 1485 end do 1486 end do 1487 write(ab_out,'(a)')' ' 1488 end do 1489 1490 !Write the q-gradient of the Polarization response 1491 write(ab_out,*)' First real-space moment of the polarization response ' 1492 write(ab_out,*)' to an atomic displacementatom, in cartesian coordinates,' 1493 write(ab_out,*)' (1/ucvol factor not included),' 1494 write(ab_out,*)' efidir atom atddir qgrdir real part imaginary part' 1495 do iq1dir=1,3 1496 do iq2dir=1,3 1497 do iatdir=1,3 1498 do iatom=1,matom 1499 1500 if (cartflg(iatom,iatdir,iq2dir,iq1dir)==1) then 1501 1502 write(ab_out,'(4(i5,3x),2(1x,f20.10))') iq2dir,iatom,iatdir,iq1dir, & 1503 & dqpol_cart(re,iatom,iatdir,iq2dir,iq1dir),dqpol_cart(im,iatom,iatdir,iq2dir,iq1dir) 1504 1505 end if 1506 1507 end do 1508 end do 1509 end do 1510 write(ab_out,*)' ' 1511 end do 1512 1513 !Write the electronic (frozen-ion) contribution to the piezoelectric tensor 1514 !(R.M. Martin, PRB 5, 1607 (1972)) 1515 write(ab_out,'(a)')' ' 1516 write(ab_out,'(a)')' Electronic (clamped-ion) contribution to the piezoelectric tensor,' 1517 write(ab_out,'(a)')' in cartesian coordinates, (from quadrupole calculation)' 1518 write(ab_out,'(a)')' atddir qgrdir efidir real part imaginary part' 1519 do iq1dir=1,3 1520 gamma=iq1dir 1521 do iq2dir=1,3 1522 alpha=iq2dir 1523 do iatdir=1,3 1524 beta=iatdir 1525 1526 piezore=zero 1527 piezoim=zero 1528 do iatom=1,matom 1529 1530 if (cartflg(iatom,iatdir,iq2dir,iq1dir)==1) then 1531 1532 piezore=piezore+( qdrptens_cart(re,iatom,beta,alpha,gamma)-qdrptens_cart(re,iatom,alpha,gamma,beta) & 1533 & + qdrptens_cart(re,iatom,gamma,beta,alpha) ) 1534 1535 piezoim=piezoim+( qdrptens_cart(im,iatom,beta,alpha,gamma)-qdrptens_cart(im,iatom,alpha,gamma,beta) & 1536 & + qdrptens_cart(im,iatom,gamma,beta,alpha) ) 1537 end if 1538 1539 end do 1540 1541 piezore=-piezore*half/ucvol 1542 piezoim=-piezoim*half/ucvol 1543 1544 write(ab_out,'(3(i5,3x),2(1x,f20.10))') beta,gamma,alpha,piezore,piezoim 1545 1546 end do 1547 end do 1548 write(ab_out,'(a)')' ' 1549 end do 1550 write(ab_out,'(80a)')('=',ii=1,80) 1551 1552 ABI_FREE(qdrptens_cart) 1553 ABI_FREE(dqpol_cart) 1554 ABI_FREE(cartflg) 1555 1556 DBG_EXIT("COLL") 1557 1558 end subroutine dfpt_qdrpout
ABINIT/m_dfpt_lw [ Modules ]
NAME
m_dfpt_lw
FUNCTION
Calculation of spatial dispertion magnitudes (quadrupole and flexoelectric tensor) from the DFPT long-wave approach.
COPYRIGHT
Copyright (C) 2018-2022 ABINIT group (MR,MS) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
NOTES
SOURCE
20 #if defined HAVE_CONFIG_H 21 #include "config.h" 22 #endif 23 24 #include "abi_common.h" 25 26 module m_dfpt_lw 27 28 use defs_basis 29 use defs_datatypes 30 use defs_abitypes 31 use defs_wvltypes 32 use m_dtset 33 use m_dtfil 34 use m_profiling_abi 35 use m_xmpi 36 use m_errors 37 use m_wfk 38 use m_nctk 39 use m_hamiltonian 40 use m_ebands 41 use m_pawrhoij 42 use m_pawtab 43 use m_wffile 44 45 use m_hdr 46 use m_io_tools, only : file_exists 47 use m_ioarr, only : read_rhor, fftdatar_write_from_hdr 48 use m_rf2, only : rf2_getidirs 49 use m_kg, only : getcut, getph, getmpw, kpgio 50 use m_abicore, only : appdig 51 use m_fft, only : fourdp 52 use m_dfpt_rhotov, only : dfpt_rhotov 53 use m_dfpt_mkvxc, only : dfpt_mkvxcggadq 54 use m_spacepar, only : hartredq, setsym 55 use m_cgtools, only : dotprod_vn 56 use m_symkpt, only : symkpt 57 use m_mpinfo, only : distrb2, initmpi_band, proc_distrb_cycle 58 use m_initylmg, only : initylmg 59 use m_inwffil, only : inwffil 60 use m_dfpt_lwwf 61 use m_dynmat, only : cart39 62 63 implicit none 64 65 private