⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 math.f90

📁 Ground state of the time-independent Gross-Pitaevskii equation
💻 F90
字号:
!**********************************************************************!! Mathematical routines!!**********************************************************************subroutine GaussHermite(n,x,w)  !  ! Calculates the abscissas and weight factors for the  ! Gauss-Hermite quadrature  !  implicit none  integer, parameter :: dp=kind(1.d0), itMax=20  real(dp), parameter :: pi=3.1415926535897932d0, epsilon=1.d-14  integer, intent(in) :: n  real(dp), dimension(n), intent(out) :: x,w  integer :: i,j,jj  real(dp) :: pimq,nmh,xold,xnew,Ha,Hb,Hc,Hp,fact  logical :: isOdd   pimq = pi**(-0.25d0)  fact = sqrt(real(2*n,dp))  nmh = 1.d0/sqrt(real(n,dp))  if(2*(n/2) /= n) then     isOdd = .true.  else     isOdd = .false.  end if  do j = n/2+1,n     ! initial guess     if(j == n/2+1) then        if(isOdd) then           xold = 0.d0        else        xold = 2.8259d-2 + 0.9778d0*nmh        end if     elseif(isOdd .and. j == n/2+2) then        xold = 2.4866d-2 + 2.0863d0*nmh     elseif(j == n) then        xold = x(n-1) + 0.5d0 + 1.2635d0*nmh     else        xold = 2.d0*x(j-1)-x(j-2)     end if     !*** find zero by Newton's method     do i=1,itMax        ! calculate value of the Hermite polynomial        Ha = 0.d0        Hb = pimq        do jj = 1,n           Hc = xold*sqrt(2./real(jj,dp))*Hb &                & - sqrt(real(jj-1,dp)/real(jj,dp))*Ha           Ha = Hb           Hb = Hc        end do                Hp = fact*Ha        xnew = xold - Hc/Hp                if(abs(xnew-xold) <= epsilon) exit        xold = xnew     end do     if(i > itMax) then        write(*,*) "Abscissa ",j," not found in GaussHermite"        stop     end if     x(j) = xnew     x(n-j+1) = -xnew     w(j) = 2.d0/Hp**2     w(n-j+1) = w(j)  end do  returnend subroutine GaussHermitesubroutine harmonic(n,nx,x,psi)  !  ! Calculates the nth eigenfunction of the harmonic oscillator  ! for k=1, m=1, hbar=1  !  implicit none  integer, parameter :: dp=kind(1.d0)  real(dp), parameter :: pi=3.1415926535897932d0  integer, intent(in) :: n,nx  real(dp), dimension(nx), intent(in) :: x  real(dp), dimension(nx), intent(out) :: psi  integer :: i  real(dp) :: norm  real(dp), external :: He,factorial  norm = 1.d0/sqrt(2.d0**n*factorial(n)*sqrt(pi))  do i=1,nx     psi(i) = He(n,x(i))*exp(-0.5d0*x(i)**2)  end do  psi=psi*normreturnend subroutine harmonicreal(kind(1.d0)) function He(n,x)  !  ! Calculates the Hermite polynomial H_n(x) by recursion  !  implicit none  integer, parameter :: dp=kind(1.d0)    integer, intent(in) :: n  real(dp), intent(in) :: x  integer :: i  real(dp) :: a,b,c  ! Verify input value  if(n < 0) then     write(*,*) 'Negative value n in function He(n,x), n=',n     stop  end if  a = 1.d0  b = 2.d0*x  if(n==0) then     c = a  elseif(n==1) then     c = b  else     do i=1,n-1        c = 2.d0*(x*b-real(i,dp)*a)        a = b        b = c     end do  end if  He = c  returnend function Hereal(kind(1.d0)) function factorial(n)  !  ! Calculates the factorial of integer n  !  ! Maximum value of n is 170  !  implicit none  integer, parameter :: dp=kind(1.d0), nmax=170  integer, intent(in) :: n  integer :: j  integer, save :: ncalc=0  real(dp), dimension(0:nmax), save :: a(0:nmax)  a(0) = 1.d0  if (n < 0 .or. n > nmax) then     write(*,*) 'Incorrect value for function factorial, n=',n      stop   elseif(n > ncalc) then     do j = ncalc+1,n        a(j) = real(j,dp)*a(j-1)     end do     ncalc = n  endif  factorial = a(n)           returnend function factorialreal(kind(1.d0)) function integrate3D(nx,ny,nz,dx,dy,dz,f)  !  ! Three-dimensional integral  !  implicit none  integer, parameter :: dp=kind(1.d0)    integer, intent(in) :: nx,ny,nz  real(dp), intent(in) :: dx,dy,dz  real(dp), dimension(nx,ny,nz), intent(in) :: f  integer :: k  real(dp), dimension(nz) :: integrand  real(dp), external :: integrate1D,integrate2D  do k = 1,nz     integrand(k) = integrate2D(nx,ny,dx,dy,f(1,1,k))  end do  integrate3D = integrate1D(nz,dz,integrand)  returnend function integrate3Dreal(kind(1.d0)) function integrate2D(nx,ny,dx,dy,f)  !  ! Two-dimensional integral  !  implicit none  integer, parameter :: dp=kind(1.d0)    integer, intent(in) :: nx,ny  real(dp), intent(in) :: dx,dy  real(dp), dimension(nx,ny), intent(in) :: f  integer :: j  real(dp), dimension(ny) :: integrand  real(dp), external :: integrate1D  do j = 1,ny     integrand(j) = integrate1D(nx,dx,f(1,j))  end do  integrate2D = integrate1D(ny,dy,integrand)  returnend function integrate2Dreal(kind(1.d0)) function integrate1D(nx,dx,f)  !  ! One-dimensional integral (trapezoidal rule)  !  implicit none  integer, parameter :: dp=kind(1.d0)    integer, intent(in) :: nx  real(dp), intent(in) :: dx  real(dp), dimension(nx), intent(in) :: f  integrate1D = (0.5d0*(f(1) + f(nx)) + sum(f(2:nx-1)))*dx  returnend function integrate1D

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -