OpenMCTDHB v2.3
|
00001 ! vim:fdm=marker 00002 00003 !--------------------------------------------------------------------------------------- 00009 MODULE modulecomputationcore 00010 IMPLICIT NONE 00011 00012 CONTAINS 00013 00014 !---------------------------------------------------------------------------------------- 00021 SUBROUTINE evaluate_error(Delta_CVec,Delta_Psi,rho_jk_zero,CVecError,PsiError,nConf) 00022 USE moduleinputvariables 00023 !---{{{ 00024 IMPLICIT NONE 00025 INTEGER*4,INTENT(IN) :: nConf 00026 COMPLEX*16,INTENT(IN) :: Delta_CVec(nConf),Delta_Psi(NDX*NDY*NDZ,MOrb) 00027 COMPLEX*16,INTENT(IN) :: rho_jk_zero(MOrb,MOrb) 00028 REAL*8,INTENT(INOUT) :: CVecError,PsiError 00029 COMPLEX*16 :: complexPsiError,O_jk 00030 00031 INTEGER :: j,k 00032 00033 CVecError = 0.d0 00034 PsiError = 0.d0 00035 complexPsiError = (0.d0,0.d0) 00036 00037 !compute the error coming from the coefficient vector 00038 CALL normvxz(Delta_CVec,CVecError,nConf) 00039 CVecError = 1.d0 / 4.d0 * CVecError**2 00040 00041 !compute the error coming from the orbitals 00042 DO j=1,MOrb 00043 00044 DO k=1,MOrb 00045 00046 CALL vvaxzz (Delta_Psi(:,j),Delta_Psi(:,k),O_jk,NDX*NDY*NDZ) ! O_jk = <Delta phi_j|Delta phi_k> 00047 complexPsiError = complexPsiError + O_jk * rho_jk_zero(j,k) 00048 00049 END DO 00050 00051 END DO 00052 00053 PsiError = DBLE(complexPsiError) 00054 00055 00056 IF (ABS(IMAG(complexPsiError))>1.0D-14) THEN 00057 00058 write(*,*)"complexPsiError",complexPsiError 00059 00060 END IF 00061 !---}}} 00062 END SUBROUTINE evaluate_error 00063 00064 00065 !---------------------------------------------------------------------------------- 00073 SUBROUTINE FuncOrbs(AbsTime,Psi_WORK,DtPsi_WORK,CData,RData,IData,LData) 00074 USE moduleinputvariables,ONLY:NDX,NDY,NDZ,MOrb,Dims,lambda0 00075 !---{{{ evaluates DtPsi of the orbitals, i.e. the right hand side of the 00076 ! orbital EOM of MCTDHB 00077 ! 00078 ! |phi_j^dot> = prefactor P [ h |phi_j>} + Sum_ksql (rho^-1)_jk rho_ksql W_sl |phi_k> ] 00079 ! for j=1,...,MOrb 00080 ! and where P = [1 - Sum_{n=1}^MOrb |phi_{n}><phi_{n}| ] 00081 00082 ! if LData = .true. THEN prefactor = -1 00083 ! if LData = .false. THEN prefactor = -i 00084 00085 00086 IMPLICIT NONE 00087 REAL*8,INTENT(IN) :: AbsTime 00088 COMPLEX*16, DIMENSION(NDX*NDY*NDZ*MOrb), INTENT(INOUT):: Psi_WORK 00089 COMPLEX*16, DIMENSION(NDX*NDY*NDZ*MOrb), INTENT(OUT) :: DtPsi_WORK 00090 COMPLEX*16, DIMENSION(NDX*NDY*NDZ,MOrb) :: Psi 00091 COMPLEX*16, DIMENSION(NDX*NDY*NDZ,MOrb) :: DtPsi 00092 COMPLEX*16, DIMENSION(NDX*NDY*NDZ,MOrb) :: prefactor_hPsi,Chi 00093 COMPLEX*16, DIMENSION(NDX*NDY*NDZ,MOrb) :: prefactor_W_jjj 00094 COMPLEX*16, DIMENSION(NDX*NDY*NDZ) :: Wsl,Wsl_phi_q 00095 COMPLEX*16, DIMENSION(NDX*NDY*NDZ,MOrb) :: projected_Chi 00096 COMPLEX*16, INTENT(IN) :: CData(MOrb,MOrb,MOrb,MOrb,2) 00097 REAL*8 :: RData(10) 00098 INTEGER,INTENT(IN) :: IData(30) 00099 logical,INTENT(IN) :: LData 00100 logical :: Relax 00101 00102 INTEGER :: s,l,q,j,k,m,error,i,propDirection 00103 COMPLEX*16 :: rho_jk(MOrb,MOrb),rho_ijkl(MOrb,MOrb,MOrb,MOrb) 00104 COMPLEX*16 :: Inv_rho_jk(MOrb,MOrb), WorkMat(MOrb,MOrb) 00105 COMPLEX*16 :: dicht4(MOrb,MOrb),workr(3*MOrb) 00106 REAL*8 :: dicht3(MOrb,2) 00107 00108 COMPLEX*16 :: prefactor 00109 COMPLEX*16 :: defect,check(MOrb),Ovlp 00110 REAL*8 :: norm 00111 00112 00113 propDirection = IData(1) 00114 Relax = LData 00115 error = 0 00116 Chi = (0.d0,0.d0) 00117 projected_Chi = (0.d0,0.d0) 00118 00119 00120 Psi = RESHAPE(Psi_WORK,(/NDX*NDY*NDZ,MOrb/)) 00121 DtPsi = RESHAPE(DtPsi_WORK,(/NDX*NDY*NDZ,MOrb/)) 00122 00123 !maybe remove this later, may not be neccessary (but check!) 00124 CALL schmidtortho (Psi,NDX*NDY*NDZ,MOrb,error) 00125 CALL schmidtortho (Psi,NDX*NDY*NDZ,MOrb,error) 00126 00127 IF (error.ne.0) THEN 00128 00129 write(*,*)"schmidtortho failed",error 00130 STOP 00131 00132 END IF 00133 00134 IF (Relax) THEN 00135 prefactor = propDirection * (-1.d0,0.d0) 00136 ELSE 00137 prefactor = propDirection * (0.d0,-1.d0) 00138 END IF 00139 00140 !---------regularize the 1-particle density matrix if neccessary--------- 00141 !-- compute the inverse of the first order RDM 00142 00143 rho_jk = CData(:,:,1,1,1) 00144 rho_ijkl = CData(:,:,:,:,2) 00145 00146 error = 0 00147 WorkMat = rho_jk 00148 CALL density(Inv_rho_jk,WorkMat,dicht3,dicht4,workr) 00149 00150 IF (error .ne. 0) THEN 00151 write(*,*) 'rho_jk not positive definite error',error 00152 STOP 00153 END IF 00154 00155 !--- make sure that every orbital is normalized. It should be anyway!---- 00156 DO j=1,MOrb 00157 00158 CALL normvxz(Psi(:,j),norm,NDX*NDY*NDZ) 00159 ! write(*,*)j,"norm",norm 00160 IF (ABS(norm-1.d0)<1.d-14 ) THEN 00161 Psi(:,j) = Psi(:,j) / norm 00162 ELSE 00163 Psi(:,j) = Psi(:,j) / norm 00164 CALL normvxz(Psi(:,j),norm,NDX*NDY*NDZ) 00165 END IF 00166 00167 END DO 00168 00169 CALL get_hPsi(MOrb,NDX,NDY,NDZ,Dims,Psi,prefactor_hPsi) 00170 prefactor_hPsi=prefactor*prefactor_hPsi 00171 00172 !--------- |chi_j> = prefactor * h |phi_j> ------------------------ 00173 Chi = prefactor_hPsi 00174 00175 00176 DO s=1,MOrb 00177 DO l=1,MOrb 00178 CALL get_Wsl(Wsl,s,l,Psi) 00179 DO q=1,MOrb 00180 00181 CALL get_Wsl_phi_q(Wsl,Psi(:,q),Wsl_phi_q) 00182 00183 DO j=1,MOrb 00184 DO k=1,MOrb 00185 00186 Chi(:,j) = Chi(:,j) + prefactor* Inv_rho_jk(j,k)*rho_ijkl(k,s,q,l)*Wsl_phi_q 00187 00188 END DO 00189 END DO 00190 00191 END DO 00192 END DO 00193 END DO 00194 00195 CALL projector_MCTDHB(Chi,DtPsi,Psi) 00196 Chi = DtPsi !--DO another projection 00197 CALL projector_MCTDHB(Chi,DtPsi,Psi) 00198 Chi = DtPsi !--DO another projection 00199 CALL projector_MCTDHB(Chi,DtPsi,Psi) 00200 00201 !---- test the orthogonality of Psi and DtPsi 00202 DO j=1,MOrb 00203 00204 ! CALL normvxz(DtPsi(:,j),norm,NDX*NDY*NDZ) 00205 DO k=1,MOrb 00206 00207 CALL vvaxzz (Psi(:,j),DtPsi(:,k),defect,NDX*NDY*NDZ) 00208 IF (ABS(defect)>1.d-10) THEN 00209 write(*,*)j,k,"<Psi_j|DtPsi_k>",defect 00210 ! read(*,*) 00211 END IF 00212 00213 END DO 00214 00215 END DO 00216 00217 Psi_WORK = RESHAPE(Psi,(/NDX*NDY*NDZ*MOrb/)) 00218 DtPsi_WORK = RESHAPE(DtPsi,(/NDX*NDY*NDZ*MOrb/)) 00219 00220 00221 !write(*,*)"-----leave FuncOrbs-------------" 00222 !---}}} 00223 END SUBROUTINE FuncOrbs 00224 00225 !---------------------------------------------------------------------------------- 00235 SUBROUTINE FuncCVecBandMat(AbsTime,CVec,DtCVec,BandMat,RData,IData,LData) 00236 USE moduleparameters 00237 USE moduledefaults,ONLY:nConf,nSuperDiags 00238 !---{{{ 00239 IMPLICIT NONE 00240 00241 COMPLEX*16,parameter :: alpha=(1.d0,0.d0) 00242 COMPLEX*16,parameter :: beta=(0.d0,0.d0) 00243 INTEGER,parameter :: incx=1 00244 INTEGER,parameter :: incy=1 00245 00246 INTEGER, INTENT(IN) :: IData(30) 00247 REAL*8, INTENT(IN) :: AbsTime,RData(10) 00248 COMPLEX*16,INTENT(IN) :: CVec(nConf),BandMat(nSuperDiags+1,nConf) 00249 logical, INTENT(IN) :: LData 00250 logical :: Relax 00251 00252 COMPLEX*16,INTENT(OUT) :: DtCVec(nConf) 00253 REAL*8 :: PropDirection 00254 00255 IF (Abs(IData(1)).ne.1) THEN 00256 write(*,*)"illegal propagation direction in FuncCVecBandMat",IData(1) 00257 END IF 00258 00259 PropDirection = IData(1) * 1.d0 00260 Relax = LData 00261 00262 CALL ZHBMV ( 'L', nConf, nSuperDiags, alpha, BandMat, nSuperDiags+1, CVec, incx, beta, DtCVec, incy ) 00263 00264 IF(Relax) THEN 00265 DtCVec = DtCVec * (-1.d0,0.d0) 00266 ELSE 00267 DtCVec = DtCVec * (0.d0,-1.d0) 00268 END IF 00269 00270 DtCVec = PropDirection * DtCVec 00271 00272 !---}}} 00273 END SUBROUTINE FuncCVecBandMat 00274 00275 !---------------------------------------------------------------------------------- 00283 SUBROUTINE get_FullHamiltonianBandMatrix(NPar,MOrb,NDX,NDY,NDZ,Dims,nConf,& 00284 nSuperDiags,lambda0,Psi,BandMat) 00285 !---{{{ 00286 IMPLICIT NONE 00287 INTEGER,INTENT(IN) :: NPar,MOrb,NDX,NDY,NDZ,Dims,nConf,nSuperDiags 00288 REAL*8,INTENT(IN) :: lambda0 00289 COMPLEX*16,INTENT(IN) :: Psi(NDX*NDY*NDZ,MOrb) 00290 COMPLEX*16 :: h_jk(MOrb,MOrb) 00291 COMPLEX*16,INTENT(OUT) :: BandMat(nSuperDiags+1,nConf) 00292 INTEGER :: m,n,n1,n2,L 00293 REAL*8 :: dn1,dn2 00294 COMPLEX*16 :: W1112,W1222,W1122,W1212,W1221 00295 COMPLEX*16 :: W1111,W2222,H_mn 00296 00297 BandMat = (0.d0,0.d0) 00298 H_mn=(0.d0,0.d0) 00299 00300 IF((MOrb>2).or.(MOrb<1)) THEN 00301 WRITE(*,*) "SORRY, YOU WILL HAVE TO IMPLEMENT THIS IN get_FullHamiltonianBandMatrix, MOrb=",MOrb 00302 STOP 00303 END IF 00304 00305 CALL get_h_jk(Psi,h_jk,NDX,NDY,NDZ,Dims,MOrb) 00306 CALL get_Wijkl(W1111,1,1,1,1,Psi) 00307 00308 IF (MOrb==1) THEN 00309 00310 BandMat(1,1) = DBLE(NPar*h_jk(1,1) + 0.5d0*W1111*NPar*(NPar-1.d0) ) 00311 00312 ELSE IF (MOrb==2) THEN 00313 00314 CALL get_Wijkl(W2222,2,2,2,2,Psi) 00315 CALL get_Wijkl(W1112,1,1,1,2,Psi) 00316 CALL get_Wijkl(W1212,1,2,1,2,Psi) 00317 CALL get_Wijkl(W1221,1,2,2,1,Psi) 00318 CALL get_Wijkl(W1222,1,2,2,2,Psi) 00319 CALL get_Wijkl(W1122,1,1,2,2,Psi) 00320 00321 DO m=1,nConf 00322 00323 L = 1 - m 00324 00325 DO n=m,MIN(nConf,m+nSuperDiags) 00326 !n1 and n2 are the occupation numbers of |R> in <L|H|R> 00327 n2 = n - 1 00328 n1 = NPar - n2 00329 dn1 = DBLE(n1) 00330 dn2 = DBLE(n2) 00331 00332 IF(n==m) THEN 00333 00334 BandMat(L+n,m) = DBLE(dn1*h_jk(1,1) + dn2*h_jk(2,2) & 00335 + 0.5d0*W1111*dn1*(dn1-1.d0) & 00336 + 0.5d0*W2222*dn2*(dn2-1.d0) & 00337 + dn1*dn2 * (W1212+W1221)) 00338 00339 ELSE IF (n==(m+1)) THEN 00340 00341 H_mn = h_jk(1,2)*DSQRT(1.d0 * (dn1+1.d0) * dn2) & 00342 + dn1 * DSQRT( dn2*(dn1+1.d0) ) * W1112 & 00343 + (dn2-1.d0)* DSQRT( (dn1+1.d0)*dn2 ) * W1222 00344 BandMat(L+n,m) = DCONJG(H_mn) 00345 00346 ELSE IF (n==(m+2)) THEN 00347 00348 H_mn = 0.5d0*DSQRT(dn2*(dn2-1.d0)*(dn1+1.d0)*(dn1+2.d0) ) * W1122 00349 BandMat(L+n,m) = DCONJG(H_mn) 00350 00351 ELSE 00352 00353 write(*,*)"I am out of bounds m,n:",m,n 00354 STOP 00355 00356 END IF 00357 00358 END DO 00359 END DO 00360 00361 END IF 00362 00363 00364 !---}}} 00365 END SUBROUTINE get_FullHamiltonianBandMatrix 00366 00367 !---------------------------------------------------------------------------------- 00378 SUBROUTINE projector_MCTDHB(Chi,projectedChi,Psi) 00379 USE moduleinputvariables,ONLY:MOrb,NDX,NDY,NDZ 00380 !---{{{ 00381 00382 IMPLICIT NONE 00383 COMPLEX*16,INTENT(IN) :: Psi(NDX*NDY*NDZ,MOrb),Chi(NDX*NDY*NDZ,MOrb) 00384 COMPLEX*16,INTENT(OUT) :: projectedChi(NDX*NDY*NDZ,MOrb) 00385 COMPLEX*16 :: Eta(NDX*NDY*NDZ) 00386 COMPLEX*16 :: Chi_new(NDX*NDY*NDZ,MOrb) 00387 COMPLEX*16 :: check(MOrb),O_jj(MOrb) 00388 REAL*8 :: norm(MOrb) 00389 INTEGER :: j,n,k 00390 00391 norm = 0.d0 00392 check = (0.d0,0.d0) 00393 projectedChi = (0.d0,0.d0) 00394 O_jj = (0.d0,0.d0) 00395 00396 !----check whether the Psi_k functions are normalized 00397 DO k=1,MOrb 00398 00399 CALL normvxz(Psi(:,k),norm(k),NDX*NDY*NDZ) 00400 IF (ABS(norm(k)-1.d0)>1.0d-14) THEN 00401 write(*,*)k,"-th phi norm:",norm(k) 00402 END IF 00403 00404 END DO 00405 00406 projectedChi = Chi 00407 00408 DO k=1,MOrb 00409 00410 Eta = (0.d0,0.d0) 00411 DO j=1,MOrb 00412 00413 CALL vvaxzz (Psi(:,j),Chi(:,k),O_jj(j),NDX*NDY*NDZ) 00414 Eta = Eta + Psi(:,j)*O_jj(j) 00415 00416 END DO 00417 00418 projectedChi(:,k) = projectedChi(:,k) - Eta 00419 00420 END DO 00421 00422 00423 !---}}} 00424 END SUBROUTINE projector_MCTDHB 00425 00426 00427 !---------------------------------------------------------------------------------- 00442 SUBROUTINE get_hPsi(MOrb,NDX,NDY,NDZ,Dims,Psi,hPsi) 00443 USE moduleallocatables,ONLY:p2over2m,V_ext 00444 USE modulefft 00445 !---{{{ 00446 IMPLICIT NONE 00447 00448 intEGER,INTENT(IN) :: MOrb,NDX,NDY,NDZ,Dims 00449 COMPLEX*16,INTENT(IN) :: Psi(NDX*NDY*NDZ,MOrb) 00450 COMPLEX*16,INTENT(OUT) :: hPsi(NDX*NDY*NDZ,MOrb) 00451 00452 INTEGER :: m,n,INFO,noGridPoints 00453 COMPLEX*16,DIMENSION(NDX*NDY*NDZ,MOrb) :: chi,phi 00454 REAL*8 :: norm 00455 00456 noGridPoints = NDX*NDY*NDZ 00457 INFO = 0 00458 !-------------------------------------------------- 00459 00460 !---compute |chi> = p^2/(2m)|Psi>--------{{{ 00461 00462 chi = Psi 00463 00464 if (Dims==1) then 00465 !--- {{{ 1d 00466 if(noGridPoints.ne.NDX) then 00467 write(*,*)"this is not good 1d" 00468 STOP 00469 endif 00470 00471 DO m=1,MOrb 00472 00473 CALL get_FFT1D(-1,NDX,chi(:,m),INFO) 00474 00475 DO n=1,noGridPoints 00476 chi(n,m)= chi(n,m) * p2over2m(n) ! multiply by (p**2)/2m (where m=1) 00477 END DO 00478 chi(:,m)=chi(:,m)/(1.d0*noGridPoints) 00479 00480 CALL get_FFT1D(1,NDX,chi(:,m),INFO) 00481 00482 END DO 00483 !---}}} 00484 00485 ELSE IF (Dims==2) THEN 00486 00487 !--- {{{ 2d 00488 IF(noGridPoints.ne.NDX*NDY) THEN 00489 write(6,*)"this is not good 2d" 00490 STOP 00491 END IF 00492 00493 DO m=1,MOrb 00494 00495 CALL get_FFT2D(-1,NDX,NDY,chi(:,m),INFO) 00496 00497 DO n=1,noGridPoints 00498 chi(n,m)= chi(n,m) * p2over2m(n) ! multiply by (p**2)/2m (where m=1) 00499 END DO 00500 chi(:,m)=chi(:,m)/(1.d0*noGridPoints) 00501 00502 CALL get_FFT2D(1,NDX,NDY,chi(:,m),INFO) 00503 00504 END DO 00505 !---}}} 00506 00507 else if (Dims==3) then 00508 00509 !--- {{{ 3d 00510 if(noGridPoints.ne.NDX*NDY*NDZ) then 00511 write(*,*)"this is not good 3d" 00512 STOP 00513 endif 00514 00515 DO m=1,MOrb 00516 00517 CALL get_FFT3D(-1,NDX,NDY,NDZ,chi(:,m),INFO) 00518 00519 DO n=1,noGridPoints 00520 chi(n,m)= chi(n,m) * p2over2m(n) ! multiply by (p**2)/2m (where m=1) 00521 END DO 00522 chi(:,m)=chi(:,m)/(noGridPoints*1.d0) 00523 00524 CALL get_FFT3D(1,NDX,NDY,NDZ,chi(:,m),INFO) 00525 00526 00527 END DO 00528 00529 !---}}} 00530 00531 else 00532 write(6,*)"more than 3d?" 00533 STOP 00534 endif 00535 00536 !}}} 00537 00538 !---compute |phi> = V|Psi> 00539 do m=1,MOrb 00540 do n=1,noGridPoints 00541 phi(n,m)=Psi(n,m)*V_ext(n) 00542 end do 00543 end do 00544 00545 hPsi = chi + phi 00546 00547 00548 !---}}} 00549 END SUBROUTINE get_hPsi 00550 00551 00552 !-------------------------------------------------------------------- 00573 SUBROUTINE get_Wsl_IMEST(Wsl,psi_s,psi_l) 00574 USE moduleinputvariables,ONLY: NDX,NDY,NDZ,Dims 00575 USE moduleallocatables, ONLY: vtilde 00576 USE modulefft 00577 !---{{{ 00578 IMPLICIT NONE 00579 COMPLEX*16,INTENT(out) :: Wsl(NDX*NDY*NDZ) 00580 COMPLEX*16,INTENT(in) :: psi_s(NDX*NDY*NDZ),psi_l(NDX*NDY*NDZ) 00581 00582 INTEGER :: i,j,k,m,n 00583 COMPLEX*16 :: fsltilde(NDX*NDY*NDZ) 00584 00585 !---------------FFT------------------------------- 00586 INTEGER :: info,noGridPoints 00587 00588 noGridPoints = NDX*NDY*NDZ 00589 00590 !compute f_sl = dx phi_s^* phi_l 00591 DO m=1,noGridPoints 00592 fsltilde(m)=DCONJG(psi_s(m))*psi_l(m) 00593 END DO 00594 00595 !get f_sl-tilde dx from f_sl dx 00596 IF (Dims==1) THEN 00597 !---{{{ 1d 00598 IF(noGridPoints.ne.NDX) THEN 00599 write(6,*)"this is not good wsl" 00600 stop 00601 END IF 00602 00603 CALL get_FFT1D(-1,NDX,fsltilde,INFO) 00604 fsltilde = 1.d0/DSQRT(1.d0*noGridPoints) * fsltilde 00605 00606 !---}}} 00607 00608 ELSE IF (Dims==2) THEN 00609 !--- {{{ 2d 00610 IF(noGridPoints.ne.NDX*NDY) THEN 00611 write(6,*)"this is not good 2d" 00612 stop 00613 END IF 00614 00615 CALL get_FFT2D(-1,NDX,NDY,fsltilde,INFO) 00616 fsltilde = 1.d0/DSQRT(1.d0*noGridPoints) * fsltilde 00617 00618 !---}}} 00619 00620 ELSE IF (Dims==3) THEN 00621 !--- {{{ 3d 00622 IF(noGridPoints.ne.NDX*NDY*NDZ) THEN 00623 write(6,*)"this is not good 3d" 00624 stop 00625 END IF 00626 00627 CALL get_FFT3D(-1,NDX,NDY,NDZ,fsltilde,INFO) 00628 fsltilde = 1.d0/DSQRT(1.d0*noGridPoints) * fsltilde 00629 00630 !---}}} 00631 END IF 00632 00633 !compute W_sl-tilde(m) = f_sl-tilde(m)*v-tilde(m)*dx 00634 DO m=1,noGridPoints 00635 Wsl(m)=fsltilde(m)*vtilde(m) 00636 END DO 00637 00638 !W_sl(i)=F^+(Wsl-tilde) 00639 IF (Dims==1) THEN 00640 !--- {{{ 1d 00641 IF(noGridPoints.ne.NDX) THEN 00642 write(6,*)"this is not good wsl" 00643 stop 00644 END IF 00645 00646 CALL get_FFT1D(1,NDX,Wsl,INFO) 00647 Wsl = 1.d0/DSQRT(1.d0*noGridPoints) * Wsl 00648 00649 !---}}} 00650 00651 ELSE IF (Dims==2) THEN 00652 !--- {{{ 2d 00653 IF(noGridPoints.ne.NDX*NDY) THEN 00654 write(6,*)"this is not good 2d" 00655 stop 00656 END IF 00657 00658 CALL get_FFT2D(1,NDX,NDY,Wsl,INFO) 00659 Wsl = 1.d0/DSQRT(1.d0*noGridPoints) * Wsl 00660 00661 !---}}} 00662 00663 ELSE IF (Dims==3) THEN 00664 !--- {{{ 3d 00665 IF(noGridPoints.ne.NDX*NDY*NDZ) THEN 00666 write(6,*)"this is not good 3d" 00667 stop 00668 END IF 00669 00670 CALL get_FFT3D(1,NDX,NDY,NDZ,Wsl,INFO) 00671 Wsl = 1.d0/DSQRT(1.d0*noGridPoints) * Wsl 00672 00673 !---}}} 00674 END IF 00675 00676 !---}}} 00677 END SUBROUTINE get_Wsl_IMEST 00678 00679 !-------------------------------------------------------------------- 00693 SUBROUTINE get_vtilde(NDX,NDY,NDZ,Dims,xi,xf,yi,yf,zi,zf,vtilde) 00694 USE moduleparameters 00695 USE moduleextensions 00696 USE modulegrid 00697 USE modulefft 00698 !---{{{ 00699 IMPLICIT NONE 00700 00701 INTEGER,INTENT(IN) :: NDX 00702 INTEGER,INTENT(IN) :: NDY 00703 INTEGER,INTENT(IN) :: NDZ 00704 INTEGER,INTENT(IN) :: Dims 00705 REAL*8,INTENT(IN) :: xi 00706 REAL*8,INTENT(IN) :: xf 00707 REAL*8,INTENT(IN) :: yi 00708 REAL*8,INTENT(IN) :: yf 00709 REAL*8,INTENT(IN) :: zi 00710 REAL*8,INTENT(IN) :: zf 00711 COMPLEX*16, INTENT(OUT) :: vtilde(NDX*NDY*NDZ) 00712 00713 COMPLEX*16 :: wtilde(NDX*NDY*NDZ) 00714 REAL*8 :: x,y,z,xall,yall,zall,dx,dy,dz 00715 INTEGER :: m,i,j,k 00716 00717 INTEGER :: info,noGridPoints 00718 00719 noGridPoints=NDX*NDY*NDZ 00720 xall = xf-xi 00721 yall = yf-yi 00722 zall = zf-zi 00723 dx = xall/(NDX*1.d0) 00724 dy = yall/(NDY*1.d0) 00725 dz = zall/(NDZ*1.d0) 00726 00727 DO m=1,noGridPoints 00728 00729 call get_ijk_from_m(m,NDX,NDY,i,j,k) 00730 x = (i-1)*dx-(xall/2.d0) 00731 y = (j-1)*dy-(yall/2.d0) 00732 z = (k-1)*dz-(zall/2.d0) 00733 00734 IF (Dims==1) THEN 00735 wtilde(m) = Wint_IMEST(x,0.d0,0.d0) 00736 ELSE IF (Dims==2) THEN 00737 wtilde(m) = Wint_IMEST(x,y,0.d0) 00738 ELSE IF (Dims==3) THEN 00739 wtilde(m) = Wint_IMEST(x,y,z) 00740 ELSE 00741 write(6,*)"more than 3d?" 00742 stop 00743 END IF 00744 00745 END DO 00746 00747 IF (Dims==1) THEN 00748 !--- {{{ 1d 00749 IF(noGridPoints.ne.NDX) THEN 00750 write(6,*)"this is not good" 00751 stop 00752 END IF 00753 00754 CALL get_FFT1D(-1,NDX,wtilde,INFO) 00755 IF (info.ne.0) write(6,*) "info get_FFT1D=",info 00756 00757 DO i=1,NDX 00758 vtilde(i) = (-1.d0)**(i-1)*wtilde(i) 00759 END DO 00760 00761 !---}}} 00762 ELSE IF (Dims==2) THEN 00763 !---{{{ 2d 00764 IF(noGridPoints.ne.NDX*NDY) THEN 00765 write(6,*)"this is not good" 00766 stop 00767 END IF 00768 00769 CALL get_FFT2D(-1,NDX,NDY,wtilde,INFO) 00770 IF (info.ne.0) write(6,*) "info get_FFT1D=",info 00771 00772 DO m=1,noGridPoints 00773 call get_ijk_from_m(m,NDX,NDY,i,j,k) 00774 vtilde(m) = (-1.d0)**(i-1+j-1)*wtilde(m) 00775 END DO 00776 00777 00778 !---}}} 00779 ELSE IF (Dims==3) THEN 00780 !---{{{ 00781 IF(noGridPoints.ne.NDX*NDY*NDZ) THEN 00782 write(6,*)"this is not good ..." 00783 stop 00784 END IF 00785 00786 CALL get_FFT3D(-1,NDX,NDY,NDZ,wtilde,INFO) 00787 IF (info.ne.0) write(6,*) "info get_FFT1D=",info 00788 00789 DO m=1,noGridPoints 00790 call get_ijk_from_m(m,NDX,NDY,i,j,k) 00791 vtilde(m) = (-1.d0)**(i-1 + j-1 + k-1) * wtilde(m) 00792 ! write(6,*)m,"vtilde(m)",vtilde(m) 00793 END DO 00794 00795 !---}}} 00796 ELSE 00797 write(6,*)"more than 3d?" 00798 stop 00799 END IF 00800 00801 !---}}} 00802 END SUBROUTINE get_vtilde 00803 00804 !---------------------------------------------------------------------------------- 00810 SUBROUTINE get_h_jk(Psi,h_jk,NDX,NDY,NDZ,Dims,MOrb) 00811 !---{{{ 00812 IMPLICIT NONE 00813 COMPLEX*16,INTENT(IN) :: Psi(NDX*NDY*NDZ,MOrb) 00814 COMPLEX*16,INTENT(OUT) :: h_jk(MOrb,MOrb) 00815 INTEGER,INTENT(IN) :: MOrb,NDX,NDY,NDZ,Dims 00816 COMPLEX*16 :: hPsi(NDX*NDY*NDZ,MOrb) 00817 INTEGER :: i,j 00818 00819 00820 hPsi=(0.0d0,0.d0) 00821 CALL get_hPsi(MOrb,NDX,NDY,NDZ,Dims,Psi,hPsi) 00822 00823 DO i=1,MOrb 00824 DO j=i,MOrb 00825 00826 CALL vvaxzz (Psi(:,i),hPsi(:,j),h_jk(i,j),NDX*NDY*NDZ) 00827 h_jk(j,i)=DCONJG(h_jk(i,j)) 00828 00829 END DO 00830 h_jk(i,i)=DBLE(h_jk(i,i)) 00831 END DO 00832 00833 !---}}} 00834 END SUBROUTINE get_h_jk 00835 00836 !---------------------------------------------------------------------------------- 00853 SUBROUTINE get_Wsl(Wsl,s,l,Psi) 00854 USE moduleinputvariables,ONLY:lambda0,NDX,NDY,NDZ,MOrb,useIMEST 00855 USE modulederivesystemvariables,ONLY:weight 00856 !---{{{ 00857 IMPLICIT NONE 00858 INTEGER,INTENT(IN) :: s,l 00859 COMPLEX*16,INTENT(IN) :: Psi(NDX*NDY*NDZ,MOrb) 00860 COMPLEX*16,INTENT(OUT) :: Wsl(NDX*NDY*NDZ) 00861 COMPLEX*16 :: PsiS(NDX*NDY*NDZ),PsiL(NDX*NDY*NDZ) 00862 INTEGER :: m 00863 00864 PsiS=Psi(:,s) 00865 PsiL=Psi(:,l) 00866 Wsl=(0.d0,0.d0) 00867 00868 IF (useIMEST) THEN 00869 00870 CALL get_Wsl_IMEST(Wsl,PsiS,PsiL) 00871 00872 ELSE 00873 00874 DO m=1,NDX*NDY*NDZ 00875 Wsl(m) = lambda0 * DCONJG(PsiS(m)/weight) * PsiL(m)/weight 00876 END DO 00877 00878 END IF 00879 00880 !---}}} 00881 END SUBROUTINE get_Wsl 00882 00883 !---------------------------------------------------------------------------------- 00889 SUBROUTINE get_Wsl_phi_q(Wsl,phi_q,Wsl_phi_q) 00890 USE moduleinputvariables,ONLY:NDX,NDY,NDZ 00891 !--- {{{ 00892 IMPLICIT NONE 00893 COMPLEX*16,INTENT(IN) :: Wsl(NDX*NDY*NDZ),phi_q(NDX*NDY*NDZ) 00894 COMPLEX*16,INTENT(OUT) :: Wsl_phi_q(NDX*NDY*NDZ) 00895 INTEGER :: i 00896 00897 Wsl_phi_q=(0.d0,0.d0) 00898 DO i=1,NDX*NDY*NDZ 00899 00900 Wsl_phi_q(i) = Wsl(i)*phi_q(i) 00901 00902 END DO 00903 00904 !}}} 00905 END SUBROUTINE get_Wsl_phi_q 00906 00907 !---------------------------------------------------------------------------------- 00913 SUBROUTINE get_Wijkl(Wijkl,i,j,k,l,Psi) 00914 USE moduleinputvariables,ONLY:NDX,NDY,NDZ,MOrb 00915 !---compute Wijkl {{{ 00916 IMPLICIT NONE 00917 INTEGER,INTENT(IN) :: i,j,k,l 00918 COMPLEX*16,INTENT(IN) :: Psi(NDX*NDY*NDZ,MOrb) 00919 COMPLEX*16,INTENT(OUT) :: Wijkl 00920 00921 COMPLEX*16 :: PsiI(NDX*NDY*NDZ),PsiK(NDX*NDY*NDZ) 00922 COMPLEX*16 :: Wjl(NDX*NDY*NDZ) 00923 INTEGER :: m 00924 00925 PsiI = Psi(:,i) 00926 PsiK = Psi(:,k) 00927 Wijkl=(0.d0,0.d0) 00928 00929 CALL get_Wsl(Wjl,j,l,Psi) 00930 00931 DO m=1,NDX*NDY*NDZ 00932 Wijkl = Wijkl + DCONJG(PsiI(m)) * Wjl(m) * PsiK(m) 00933 END DO 00934 00935 00936 !---}}} 00937 END SUBROUTINE get_Wijkl 00938 00939 !---------------------------------------------------------------------------------- 00946 SUBROUTINE get_rho_jk(nConf,MOrb,NPar,CVec,rho_jk) 00947 !---{{{ 00948 IMPLICIT NONE 00949 INTEGER,INTENT(IN) :: nConf,MOrb,NPar 00950 COMPLEX*16,INTENT(IN) :: CVec(nConf) 00951 COMPLEX*16,INTENT(OUT) :: rho_jk(MOrb,MOrb) 00952 INTEGER :: i,j,n,n1,n2 00953 00954 rho_jk = (0.d0,0.d0) 00955 00956 orbitalif: IF (MOrb == 1) THEN 00957 00958 rho_jk(1,1) = 1.0d0*NPar 00959 00960 ELSE IF (MOrb == 2) THEN 00961 00962 DO n=1,nConf 00963 00964 n1 = nConf-n 00965 n2 = NPar-n1 00966 00967 rho_jk(1,1) = rho_jk(1,1) + DCONJG(CVec(n))*CVec(n) * n1 00968 rho_jk(2,2) = rho_jk(2,2) + DCONJG(CVec(n))*CVec(n) * n2 00969 00970 END DO 00971 00972 DO n=1,nConf-1 00973 00974 n1 = nConf-n 00975 n2 = NPar-n1 00976 00977 rho_jk(1,2) = rho_jk(1,2) + DCONJG(CVec(n))*CVec(n+1) * DSQRT(1.D0*n1*(n2+1)) 00978 rho_jk(2,1) = DCONJG(rho_jk(1,2)) 00979 00980 END DO 00981 00982 ELSE orbitalif 00983 00984 WRITE(*,*)"INVALID NUMBER OF ORBITALS, MOrb = ",MOrb 00985 WRITE(*,*)"MORE THAN M=2 ORBITALS ARE NOT IMPLEMENTED IN get_rho_jk" 00986 STOP 00987 00988 END IF orbitalif 00989 00990 00991 !---}}} 00992 END SUBROUTINE get_rho_jk 00993 00994 !---------------------------------------------------------------------------------- 01000 SUBROUTINE get_rho_ijkl(nConf,MOrb,NPar,CVec,rho_ijkl) 01001 USE moduleparameters 01002 !---{{{ Evaluate the two-body reduced density matrix elements rho_ijkl for MOrb = 1,2 ONLY 01003 IMPLICIT NONE 01004 INTEGER,INTENT(IN) :: nConf,MOrb,NPar 01005 COMPLEX*16,INTENT(IN) :: CVec(nConf) 01006 COMPLEX*16,INTENT(OUT) :: rho_ijkl(MOrb,MOrb,MOrb,MOrb) 01007 INTEGER :: i,j,k,l,n,n1,n2 01008 01009 rho_ijkl = ZERO 01010 01011 orbitalif: IF (MOrb == 1) THEN 01012 01013 rho_ijkl(1,1,1,1) = 1.0d0*NPar * (NPar-1.d0) 01014 01015 ELSE IF (MOrb == 2) THEN 01016 01017 DO n=1,nConf 01018 01019 n1 = nConf-n 01020 n2 = NPar-n1 01021 01022 ! rho_kkkk 01023 rho_ijkl(1,1,1,1) = rho_ijkl(1,1,1,1) + DCONJG(CVec(n))*CVec(n) * n1 * (n1-1.d0) 01024 rho_ijkl(2,2,2,2) = rho_ijkl(2,2,2,2) + DCONJG(CVec(n))*CVec(n) * n2 * (n2-1.d0) 01025 01026 ! rho_ksks 01027 rho_ijkl(1,2,1,2) = rho_ijkl(1,2,1,2) + DCONJG(CVec(n))*CVec(n) * n1 * n2 01028 01029 END DO 01030 01031 rho_ijkl(1,2,2,1) = rho_ijkl(1,2,1,2) 01032 rho_ijkl(2,1,2,1) = rho_ijkl(1,2,1,2) 01033 rho_ijkl(2,1,1,2) = rho_ijkl(1,2,1,2) 01034 01035 DO n=1,nConf-1 01036 01037 n1 = nConf-n 01038 n2 = NPar-n1 01039 rho_ijkl(1,1,1,2) = rho_ijkl(1,1,1,2) + DCONJG(CVec(n))*CVec(n+1) * (n1-1.d0) * DSQRT(1.D0*n1*(n2+1)) 01040 rho_ijkl(1,2,2,2) = rho_ijkl(1,2,2,2) + DCONJG(CVec(n))*CVec(n+1) * n2 * DSQRT(1.D0*n1*(n2+1)) 01041 01042 END DO 01043 01044 rho_ijkl(1,1,2,1) = rho_ijkl(1,1,1,2) 01045 rho_ijkl(1,2,1,1) = DCONJG(rho_ijkl(1,1,1,2)) 01046 rho_ijkl(2,1,1,1) = DCONJG(rho_ijkl(1,1,1,2)) 01047 rho_ijkl(2,1,2,2) = rho_ijkl(1,2,2,2) 01048 rho_ijkl(2,2,2,1) = DCONJG(rho_ijkl(1,2,2,2)) 01049 rho_ijkl(2,2,1,2) = DCONJG(rho_ijkl(1,2,2,2)) 01050 01051 DO n=1,nConf-2 01052 01053 n1 = nConf-n 01054 n2 = NPar-n1 01055 rho_ijkl(1,1,2,2) = rho_ijkl(1,1,2,2) + DCONJG(CVec(n))*CVec(n+2) * DSQRT((n1-1.d0) * n1 *(n2+1.d0) * (n2+2.d0)) 01056 01057 END DO 01058 01059 rho_ijkl(2,2,1,1) = DCONJG(rho_ijkl(1,1,2,2)) 01060 01061 ELSE orbitalif 01062 01063 WRITE(*,*)"INVALID NUMBER OF ORBITALS, MOrb = ",MOrb 01064 WRITE(*,*)"MORE THAN M=2 ORBITALS ARE NOT IMPLEMENTED IN get_rho_ijkl" 01065 STOP 01066 01067 END IF orbitalif 01068 01069 ! }}} 01070 END SUBROUTINE get_rho_ijkl 01071 01072 01073 !---------------------------------------------------------------------------------- 01078 SUBROUTINE get_mu_kj(AbsTime,mu_kj,Psi,rho_jk,rho_ijkl) 01079 USE moduleinputvariables,ONLY:NDX,NDY,NDZ,MOrb,Dims,lambda0,NPar 01080 !---{{{ evaluates 01081 ! 01082 ! mu_kj = Sum_{q=1}^M { rho_kq h_jq + Sum_{s,l=0}^M rho_ksql W_jsql } 01083 ! for k,j=1,...,MOrb 01084 01085 IMPLICIT NONE 01086 REAL*8,INTENT(IN) :: AbsTime 01087 COMPLEX*16, DIMENSION(NDX*NDY*NDZ,MOrb),INTENT(IN) :: Psi 01088 COMPLEX*16, INTENT(IN) :: rho_jk(MOrb,MOrb),rho_ijkl(MOrb,MOrb,MOrb,MOrb) 01089 COMPLEX*16, INTENT(OUT) :: mu_kj(MOrb,MOrb) 01090 INTEGER :: s,l,q,j,k 01091 01092 COMPLEX*16 :: h_jk(MOrb,MOrb) 01093 COMPLEX*16 :: Wjsql 01094 01095 mu_kj = (0.d0,0.d0) 01096 Wjsql = (0.d0,0.d0) 01097 01098 CALL get_h_jk(Psi,h_jk,NDX,NDY,NDZ,Dims,MOrb) 01099 01100 DO k=1,MOrb 01101 DO j=1,MOrb 01102 DO q=1,MOrb 01103 DO s=1,MOrb 01104 DO l=1,MOrb 01105 01106 CALL get_Wijkl(Wjsql,j,s,q,l,Psi) 01107 mu_kj(k,j)=mu_kj(k,j) + rho_ijkl(k,s,q,l)*Wjsql 01108 01109 END DO 01110 END DO 01111 01112 mu_kj(k,j)=mu_kj(k,j) + rho_jk(k,q) * h_jk(j,q) 01113 01114 END DO 01115 END DO 01116 END DO 01117 01118 mu_kj = mu_kj/Npar 01119 01120 01121 !---}}} 01122 END SUBROUTINE get_mu_kj 01123 01124 01125 01126 01127 01128 END MODULE modulecomputationcore