0% found this document useful (0 votes)
335 views10 pages

Programs To Calculate Madelung

This Fortran program calculates Madelung's constant for different lattice sizes by: 1. Generating a 3D lattice array with assigned charges and calculating the electrostatic potential from each point. 2. Calculating Madelung's constant from the total potential and lattice parameters. 3. Repeating the calculation for lattice sizes from 1 to 250 and writing the results to an output file. 4. Optionally performing a screened calculation by including an exponential screening term dependent on lattice spacing.

Uploaded by

Gaurav Gautam
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
335 views10 pages

Programs To Calculate Madelung

This Fortran program calculates Madelung's constant for different lattice sizes by: 1. Generating a 3D lattice array with assigned charges and calculating the electrostatic potential from each point. 2. Calculating Madelung's constant from the total potential and lattice parameters. 3. Repeating the calculation for lattice sizes from 1 to 250 and writing the results to an output file. 4. Optionally performing a screened calculation by including an exponential screening term dependent on lattice spacing.

Uploaded by

Gaurav Gautam
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Programs to calculate Madelungs 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)+(((x2y2)*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

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

You might also like