OpenMCTDHB v2.3
|
00001 ! vim:fdm=marker: 00002 !------------------------------------------------------------------------ 00008 MODULE modulegrid 00009 IMPLICIT NONE 00010 00011 CONTAINS 00012 00013 !------------------------------------------------------------------------ 00018 SUBROUTINE get_positionGrid(pos_i,pos_f,gdim,grid) 00019 !---{{{ 00020 IMPLICIT NONE 00021 00022 INTEGER,INTENT(IN) :: gdim !< number of grid points in this direction 00023 REAL*8,INTENT(IN) :: pos_i !< left border of box 00024 REAL*8,INTENT(IN) :: pos_f !< right border of box( =last grid point + dx) 00025 REAL*8,INTENT(OUT) :: grid(gdim) !< the position grid 00026 00027 REAL*8 :: dx 00028 INTEGER :: i 00029 00030 dx = (pos_f-pos_i)/(1.d0*gdim) 00031 DO i=1,gdim 00032 grid(i) = pos_i+(i-1)*dx 00033 END DO 00034 !---}}} 00035 END SUBROUTINE get_positionGrid 00036 00037 !------------------------------------------------------------------------ 00047 SUBROUTINE get_momentumGrid(xl,xu,gdim,momentumGrid) 00048 USE moduleparameters, ONLY: PI 00049 !---{{{ returns momentum grid in ascending order 00050 IMPLICIT NONE 00051 00052 INTEGER,INTENT(IN) :: gdim !< number of grid points in this direction 00053 REAL*8,INTENT(IN) :: xl !< left border of box 00054 REAL*8,INTENT(IN) :: xu !< right border of box( =last grid point + dx) 00055 REAL*8,INTENT(OUT) :: momentumGrid(gdim) !< array of momentum space grid points in ascending order 00056 00057 REAL*8 :: dp 00058 INTEGER :: i 00059 00060 IF (gdim>1) then 00061 dp = 2.d0*PI/(xu-xl) 00062 00063 IF (MOD(gdim,2)==0) then !gdim even 00064 00065 DO i=1,gdim 00066 momentumGrid(i)=(i-gdim/2)*dp ! e.g.: (-dp,0,dp,2dp) 00067 END DO 00068 00069 ELSE ! gdim uneven 00070 00071 DO i=1,gdim 00072 momentumGrid(i)=(i-gdim/2-1)*dp ! e.g.: (-2dp,-dp,0,dp,2dp) 00073 END DO 00074 00075 END IF 00076 00077 ELSE IF (gdim==1) then 00078 00079 momentumGrid(1) = 0.d0 00080 00081 ELSE 00082 00083 write(*,*)"ERROR in dimension" 00084 STOP 00085 00086 END IF 00087 00088 !---}}} 00089 END SUBROUTINE get_momentumGrid 00090 00091 00092 !------------------------------------------------------------------------ 00102 SUBROUTINE get_FFTmomentumGrid(pos_i,pos_f,gdim,FFTmomentumGrid) 00103 USE moduleparameters,ONLY:PI 00104 !---{{{ returns momentum grid in fft order 00105 IMPLICIT NONE 00106 00107 INTEGER,INTENT(IN) :: gdim !< the number of grid points in this direction 00108 REAL*8,INTENT(IN) :: pos_i !< left border of the box 00109 REAL*8,INTENT(IN) :: pos_f !< right border of the box ( =last grid point + dx) 00110 REAL*8,INTENT(OUT) :: FFTmomentumGrid(gdim) !< array of momentum space grid points in FFT order 00111 00112 REAL*8 :: dp 00113 INTEGER :: i 00114 00115 dp = 2.d0*pi/(pos_f-pos_i) 00116 DO i=1,gdim 00117 FFTmomentumGrid(i) = (i-1)*dp 00118 END DO 00119 00120 DO i=gdim/2+2,gdim !put momenta in FFT order (0,dp,...,N/2*dp,(-N/2+1)*dp,...,-dp) 00121 FFTmomentumGrid(i)=1.d0*(i-gdim-1)*dp 00122 END DO 00123 00124 !---}}} 00125 END SUBROUTINE get_FFTmomentumGrid 00126 00127 !------------------------------------------------------------------------ 00134 SUBROUTINE get_p2over2m(NDX,NDY,NDZ,xi,xf,yi,yf,zi,zf,Dims,p2over2m) 00135 ! {{{ 00136 IMPLICIT NONE 00137 00138 REAL*8,INTENT(IN) :: xi !< left border of box 00139 REAL*8,INTENT(IN) :: xf !< right border of box( =last grid point + dx) 00140 REAL*8,INTENT(IN) :: yi !< left border of box 00141 REAL*8,INTENT(IN) :: yf !< right border of box( =last grid point + dy) 00142 REAL*8,INTENT(IN) :: zi !< left border of box 00143 REAL*8,INTENT(IN) :: zf !< right border of box( =last grid point + dz) 00144 INTEGER,INTENT(IN) :: NDX !< number of grid points in x 00145 INTEGER,INTENT(IN) :: NDY !< number of grid points in y 00146 INTEGER,INTENT(IN) :: NDZ !< number of grid points in z 00147 INTEGER,INTENT(IN) :: Dims !< number of dimensions 00148 REAL*8,INTENT(OUT) :: p2over2m(NDX*NDY*NDZ) !< the array p^2/2m in FFT order 00149 00150 INTEGER :: i,j,k,m,n 00151 REAL*8 :: FFTmomentumGridx(NDX),FFTmomentumGridy(NDY),FFTmomentumGridz(NDZ),dpx,dpy,dpz 00152 00153 00154 FFTmomentumGridx = 0.d0 00155 FFTmomentumGridy = 0.d0 00156 FFTmomentumGridz = 0.d0 00157 00158 IF(NDX>1) THEN 00159 !---{{{ get momentumGridx in fft order 00160 CALL get_FFTmomentumGrid(xi,xf,NDX,FFTmomentumGridx) 00161 ! write(6,*)"FFTmomentumGridx",FFTmomentumGridx 00162 ! write(6,*)"xi=",xi 00163 ! write(6,*)"xf=",xf 00164 !---}}} 00165 END IF 00166 00167 IF (NDY>1) THEN 00168 !---{{{ get momentumGridy in fft order 00169 CALL get_FFTmomentumGrid(yi,yf,NDY,FFTmomentumGridy) 00170 !---}}} 00171 END IF 00172 00173 IF (NDZ>1) THEN 00174 !---{{{ get momentumGridz in fft order 00175 CALL get_FFTmomentumGrid(zi,zf,NDZ,FFTmomentumGridz) 00176 !---}}} 00177 END IF 00178 00179 DO m=1,NDX*NDY*NDZ 00180 00181 CALL get_ijk_from_m(m,NDX,NDY,i,j,k) 00182 00183 ! multiply by px**2+py**2+pz**2 00184 00185 IF(NDX>=1) THEN 00186 00187 p2over2m(m)=FFTmomentumGridx(i)**2 00188 ! write(6,*)"i",i,"FFTmomentumGridx(i)",FFTmomentumGridx(i) 00189 END IF 00190 00191 IF (NDY>1) THEN 00192 p2over2m(m) = p2over2m(m) + FFTmomentumGridy(j)**2 00193 END IF 00194 00195 IF (NDZ>1) THEN 00196 p2over2m(m) = p2over2m(m) + FFTmomentumGridz(k)**2 00197 END IF 00198 00199 p2over2m(m) = 0.5d0 * p2over2m(m) 00200 00201 END DO 00202 00203 !---}}} 00204 END SUBROUTINE get_p2over2m 00205 00206 !------------------------------------------------------------------------ 00215 SUBROUTINE get_ijk_from_m(m,NDX,NDY,i,j,k) 00216 !---{{{ 00217 IMPLICIT NONE 00218 INTEGER,INTENT(IN) :: m !< the index that runs over all grid points in 1d,2d and 3d 00219 INTEGER,INTENT(IN) :: NDX !< number of grid points in x-direction 00220 INTEGER,INTENT(IN) :: NDY !< number of grid points in y-direction 00221 INTEGER,INTENT(OUT) :: i !< index of grid point x_i = positionGridx(i) 00222 INTEGER,INTENT(OUT) :: j !< index of grid point y_j = positionGridx(j) 00223 INTEGER,INTENT(OUT) :: k !< index of grid point z_k = positionGridx(k) 00224 00225 00226 INTEGER :: n 00227 00228 n = m 00229 k = (n-1)/(NDX*NDY) + 1 00230 n = n-(k-1)*NDX*NDY 00231 j = (n-1)/NDX + 1 00232 n = n-(j-1)*NDX 00233 i = n 00234 00235 !---}}} 00236 END SUBROUTINE get_ijk_from_m 00237 00238 !----------------------------------------------------------------------- 00245 SUBROUTINE check_grid(Dims,NDX,NDY,NDZ) 00246 !---{{{ 00247 IMPLICIT NONE 00248 INTEGER,INTENT(IN) :: Dims !< number of dimensions used in the current problem 00249 INTEGER,INTENT(IN) :: NDX !< number of dimensions used in direction x 00250 INTEGER,INTENT(IN) :: NDY !< number of dimensions used in direction y 00251 INTEGER,INTENT(IN) :: NDZ !< number of dimensions used in direction z 00252 00253 IF((NDY>NDX).or. (NDZ>NDY)) THEN 00254 write(6,*)"bad grid dimensions" 00255 write(6,*)"correct form : NDX >= NDY >= NDZ" 00256 write(6,*)"NDX = ",NDX 00257 write(6,*)"NDY = ",NDY 00258 write(6,*)"NDZ = ",NDZ 00259 STOP 00260 END IF 00261 00262 IF ((Dims==1).and.((NDY>1).or.(NDZ>1))) THEN 00263 write(6,*)"inconsistency in grid and dimensions" 00264 write(6,*)"Dims = ",Dims 00265 write(6,*)"NDX = ",NDX 00266 write(6,*)"NDY = ",NDY 00267 write(6,*)"NDZ = ",NDZ 00268 STOP 00269 ELSE IF ((Dims==2).and.((NDZ>1).or.(NDY<2))) THEN 00270 write(6,*)"inconsistency in grid and dimensions" 00271 write(6,*)"Dims = ",Dims 00272 write(6,*)"NDX = ",NDX 00273 write(6,*)"NDY = ",NDY 00274 write(6,*)"NDZ = ",NDZ 00275 STOP 00276 ELSE IF ((Dims==3).and.(NDZ<2)) THEN 00277 write(6,*)"inconsistency in grid and dimensions" 00278 write(6,*)"Dims = ",Dims 00279 write(6,*)"NDX = ",NDX 00280 write(6,*)"NDY = ",NDY 00281 write(6,*)"NDZ = ",NDZ 00282 STOP 00283 END IF 00284 00285 IF (NDX<8) THEN 00286 write(6,*)"grid too small. NDX must be >= 8" 00287 STOP 00288 END IF 00289 !---}}} 00290 END SUBROUTINE check_grid 00291 00292 !----------------------------------------------------------------------- 00299 SUBROUTINE get_defaultOrbitals(NDX,NDY,NDZ,Dims,gridx,gridy,gridz,MOrb,Psi) 00300 !---{{{ 00301 IMPLICIT NONE 00302 INTEGER,INTENT(IN) :: NDX !< number of dimensions used in direction x 00303 INTEGER,INTENT(IN) :: NDY !< number of dimensions used in direction y 00304 INTEGER,INTENT(IN) :: NDZ !< number of dimensions used in direction z 00305 INTEGER,INTENT(IN) :: Dims !< number of dimensions used in the current problem 00306 INTEGER,INTENT(IN) :: MOrb !< number of orbitals used in the current problem 00307 REAL*8,INTENT(IN) :: gridx(NDX) !< x-position grid 00308 REAL*8,INTENT(IN) :: gridy(NDY) !< y-position grid 00309 REAL*8,INTENT(IN) :: gridz(NDZ) !< z-position grid 00310 COMPLEX*16,INTENT(OUT) :: Psi(NDX*NDY*NDZ,MOrb) !< array of default orbitals (gaussians) 00311 00312 INTEGER :: m,n,i,j,k 00313 REAL*8 :: sigmax,sigmay,sigmaz,x,y,z 00314 00315 sigmax = 1.d0 00316 sigmay = 1.d0 00317 sigmaz = 1.d0 00318 00319 IF (Dims==1) THEN 00320 00321 DO n=1,MOrb 00322 DO m=1,NDX 00323 00324 x=gridx(m) 00325 Psi(m,n) = x**(n-1)* EXP(-x**2/(2.d0*sigmax)**2) 00326 00327 END DO 00328 END DO 00329 00330 ELSE IF (Dims==2) THEN 00331 00332 DO n=1,MOrb 00333 DO m=1,NDX*NDY 00334 CALL get_ijk_from_m(m,NDX,NDY,i,j,k) 00335 x=gridx(i) 00336 y=gridy(j) 00337 00338 Psi(m,n) = x**(n-1)* EXP(-x**2/(2.d0*sigmax**2)) * EXP(-y**2/(2.d0*sigmay**2)) 00339 00340 END DO 00341 END DO 00342 00343 00344 ELSE IF (Dims==3) THEN 00345 00346 00347 DO n=1,MOrb 00348 DO m=1,NDX*NDY*NDZ 00349 00350 CALL get_ijk_from_m(m,NDX,NDY,i,j,k) 00351 x=gridx(i) 00352 y=gridy(j) 00353 z=gridz(k) 00354 00355 00356 Psi(m,n) = x**(n-1)* EXP(-x**2/(2.d0*sigmax**2)) * EXP(-y**2/(2.d0*sigmay**2)) * & 00357 EXP(-z**2/(2.d0*sigmaz**2)) 00358 00359 00360 END DO 00361 END DO 00362 00363 ELSE 00364 00365 WRITE(*,*) "ILLEGAL VALUE FOR DIMS IN get_defaulOrbitals:",Dims 00366 STOP 00367 00368 END IF 00369 00370 00371 !---}}} 00372 END SUBROUTINE get_defaultOrbitals 00373 00374 00375 00376 00377 00378 END MODULE modulegrid