Академический Документы
Профессиональный Документы
Культура Документы
print*,'Enter the size of the lattice:' read*,sizex,sizey,sizez print*,'Enter the charge at first vertex:' read*,first
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
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
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***"
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
open(1,FILE='E:\fortran\course\lab3\question3\output.txt',ACCESS='APPEND',STATUS='NEW')
write(1,*) 'X
charge'
end do end do end do Write(1,*) 'The total number of points:',count close(1) end subroutine end module
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
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