Programs to Calculate Madelung

10
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'

description

fortran programs

Transcript of Programs to Calculate Madelung

Page 1: 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'

Page 2: Programs to Calculate Madelung

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

Page 3: Programs to Calculate Madelung

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

Page 4: Programs to Calculate Madelung

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

Page 5: Programs to Calculate Madelung

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(:)

Page 6: Programs to Calculate Madelung

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

Page 7: Programs to Calculate Madelung

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

Page 8: Programs to Calculate Madelung

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.***"

Page 9: Programs to Calculate Madelung

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

Page 10: Programs to Calculate Madelung

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