Programs to Calculate Madelung
-
Upload
gaurav-gautam -
Category
Documents
-
view
110 -
download
1
description
Transcript of Programs to Calculate Madelung
Programs to calculate Madelung’s constant in fortran
program madconst
use madelung
use lattice
implicit none
integer,allocatable :: lattarray(:,:,:)
integer :: first,sizex,sizey,sizez,ox,oy,oz,i,j,k,count=0,response
real :: potential=0.0,bondlen=0.236E-9,mad=0.0,alp
print*,'Enter the size of the lattice:'
read*,sizex,sizey,sizez
print*,'Enter the charge at first vertex:'
read*,first
call coordgen(2*sizex+1,2*sizey+1,2*sizez+1,lattarray)
ox=sizex+1
oy=sizey+1
oz=sizez+1
call assignlat(lattarray,first)
call printlat(lattarray)
print*,'Plaease choose one:'
print*,'1.Calculate Madelung constant'
print*,'2.Calculate screened Madelung constant'
read*,response
if (response==1) then
do i=1,2*sizex+1
do j=1,2*sizey+1
do k=1,2*sizez+1
if (i/=ox .and. j/=oy .and. k/=oz) then
potential = potential +
coulomb(ox,oy,oz,i,j,k,bondlen,lattarray(i,j,k))
end if
count=count+1
end do
end do
end do
mad=4*pi*eps*bondlen*potential/e
print*,'Number of points included in the calculation:',count
print*,'madelung constant:',mad
else if (response==2) then
print*,'Enter the value of alpha between 0 and 1:'
read*,alp
do i=1,2*sizex+1
do j=1,2*sizey+1
do k=1,2*sizez+1
if (i/=ox .and. j/=oy .and. k/=oz) then
mad = mad +
screened(ox,oy,oz,i,j,k,bondlen,lattarray(i,j,k),alp)
end if
count=count+1
end do
end do
end do
print*,'Number of points included in the calculation:',count
print*,'madelung constant:',mad
end if
end program
module madelung
implicit none
real,parameter :: pi=3.14159265359,eps=8.8541878176E-12,e=1.60217657E-19
contains
real function coulomb(x1,x2,x3,y1,y2,y3,a,charge)
implicit none
integer :: x1,x2,x3,y1,y2,y3,charge
real :: a,sum=0
coulomb=((e*charge)/(4*pi*eps*a*sqrt((((x1-y1)*1.0)**2)+(((x2-
y2)*1.0)**2)+(((x3-y3)*1.0)**2))))
end function
real function screened(x1,x2,x3,y1,y2,y3,a,charge,alp)
implicit none
integer :: x1,x2,x3,y1,y2,y3,charge
real :: a,sum=0,alp,rijk
rijk=a*sqrt((((x1-y1)*1.0)**2)+(((x2-y2)*1.0)**2)+(((x3-y3)*1.0)**2))
screened=((exp(-alp*rijk/a))/(rijk/a))
end function
end module
module lattice
contains
subroutine coordgen(sizex,sizey,sizez,latarray)
implicit none
integer,intent(in) :: sizez,sizey,sizex
integer :: ok
integer,dimension(:,:,:),allocatable :: latarray
allocate(latarray(1:sizex,1:sizey,1:sizez),STAT=ok)
if (ok/=0) then
stop "***Cannot allocate memory***"
end if
latarray(:,:,:)=0
end subroutine
subroutine assignlat(lattice,first)
implicit none
integer,intent(inout),dimension(:,:,:) :: lattice
integer,intent(in) :: first
integer,allocatable,dimension(:) :: row
integer,allocatable,dimension(:,:) :: plane,plntemp
integer :: ok,index,charge,length,width
allocate(row(size(lattice, dim=1)),STAT=ok)
if (ok/=0) stop "***Cannot allocate memory***"
allocate(plane(1:size(lattice, dim=1),1:size(lattice, dim=2)),STAT=ok)
if (ok/=0) stop "***Cannot allocate memory***"
charge=first
do index=1,size(lattice, dim=1)
lattice(1,index,1)=charge
charge=charge*(-1)
end do
row(:)=lattice(1,:,1)
length=size(row, dim=1)
do index=2,size(lattice, dim=1)
row(:)=-1*row(:)
lattice(index,:,1)=row(:)
end do
plane(:,:)=lattice(:,:,1)
length=size(lattice, dim=1)
width=size(lattice, dim=2)
do index=2,size(lattice,dim=3)
plane(:,:)=-1*plane(:,:)
lattice(:,:,index)=plane(:,:)
end do
end subroutine
subroutine printlat(lattice)
implicit none
integer,intent(inout),dimension(:,:,:) :: lattice
integer :: index1,index2,index3,count=0
open(1,FILE='E:\fortran\course\lab3\question3\output.txt',ACCESS='APPEND',STATUS='NEW')
write(1,*) 'X Y z charge'
do index1=1,size(lattice,dim=1)
do index2=1,size(lattice,dim=2)
do index3=1,size(lattice,dim=3)
write(1,*) index1,index2,index3,lattice(index1,index2,index3)
count=count+1
end do
end do
end do
Write(1,*) 'The total number of points:',count
close(1)
end subroutine
end module
program madconst
use madelung
use lattice
implicit none
integer,allocatable :: lattarray(:,:,:)
integer :: first=1,sizex,sizey,sizez,ox,oy,oz,i,j,k,count=0,L,ok,response,index
real :: potential=0.0,bondlen=0.236E-9,mad,alp
open(2,FILE='E:\fortran\course\lab3\question3\maddata.txt',ACCESS='APPEND',STATUS='NEW')
print*,'Plaease choose one:'
print*,'1.Calculate Madelung constant'
print*,'2.Calculate screened Madelung constant'
read*,response
if (response==1) then
do L=1,250,1
sizex=L
sizey=L
sizez=L
call coordgen(2*sizex+1,2*sizey+1,2*sizez+1,lattarray)
ox=sizex+1
oy=sizey+1
oz=sizez+1
call assignlat(lattarray,first)
do i=1,2*sizex+1
do j=1,2*sizey+1
do k=1,2*sizez+1
if (i/=ox .and. j/=oy .and. k/=oz) then
potential = potential +
coulomb(ox,oy,oz,i,j,k,bondlen,lattarray(i,j,k))
end if
count=count+1
end do
end do
end do
mad=4*pi*eps*bondlen*potential/e
write(2,*) sizex,mad
deallocate(lattarray,STAT=ok)
if (ok/=0) stop "***Cannot destroy array.***"
print*,L
mad=0
potential=0
end do
else if (response==2) then
do index=0,10
alp=index/10.0
write(2,*) alp
do L=1,250,1
sizex=L
sizey=L
sizez=L
call coordgen(2*sizex+1,2*sizey+1,2*sizez+1,lattarray)
ox=sizex+1
oy=sizey+1
oz=sizez+1
call assignlat(lattarray,first)
do i=1,2*sizex+1
do j=1,2*sizey+1
do k=1,2*sizez+1
if (i/=ox .and. j/=oy .and. k/=oz) then
mad = mad +
screened(ox,oy,oz,i,j,k,bondlen,lattarray(i,j,k),alp)
end if
count=count+1
end do
end do
end do
write(2,*) sizex,mad
deallocate(lattarray,STAT=ok)
if (ok/=0) stop "***Cannot destroy array.***"
print*,L
mad=0
end do
end do
end if
close(2)
end program