回 帖 发 新 帖 刷新版面

主题:[讨论]求高手解答为什么会出错,关于跳出循环的

刚才那个错误改过来了,不是错在那里,但是现在一个循环语句又出错了
do T=1,100
   do icycle=1,ncycle
      call pre(pold)
      call volumechange
      if(box==boxn)then
        call pre(pnew)
      endif
      if(abs(pold-pnew).lt.0.1)then
      goto loop
      endif  
   enddo 
loop print(T,pnew,box**3)  
enddo
end
出错信息:
warning 1091 - Using a floating point loop variable may give unexpercted results due to rounding errors
error 1007 - ASSIGNed GOTO inside a DO loop requires the use of /INHIBIT_CHECK 10 to compile with /CHECK
------------------------------------------------------
完整程序:
program nptmc
integer::i,j,icycle,ncycle=100
real::x(:),y(:),z(:),r,box=1.0,boxn,p,pold,pnew,T,w,e,eold,enew,h=0.0,V=1.0,dv=0.1,m=1.0,K=3.18
call random_seed()
do i=1,100
   call random_number(x(i))
   call random_number(y(i))
   call random_number(z(i))
enddo


[color=FF0000]do T=1,100[/color]  
    do icycle=1,ncycle
      call pre(pold)
      call volumechange
      if(box==boxn)then
        call pre(pnew)
      endif
      if(abs(pold-pnew).lt.0.1)then
      [color=FF0000]goto loop[/color]      
      endif  
   enddo 
loop print(T,pnew,box**3)  
enddo
end


subroutine pre(p)
do i=1,100   
   do j=1,100
      if(i<j)then
        r=sqrt((x(i)-x(j))**2+(y(i)-y(j))**2+(z(i)-z(j))**2)
        r=abs(r-box*nint(r/box))
        h=h+r*4.*(-12.*(1./r)**13+6.*(1./r)**7)
      end if
   end do
end do      
p=m/box**3*K*T-1.0/(3.0*box**3)*h
return
end

      
subroutine volumechange
call energy(eold)
vold=box**3
vnew=vold+(2*ranf()-1)*dV
if(vnew.lt.0) return
boxn=vnew**(1/3)
do i=1,100
   x(i)=x(i)*boxn/box
   y(i)=y(i)*boxn/box
   z(i)=z(i)*boxn/box
enddo
call energy(enew)
w=min(1,exp(-(enew/2.-eold/2.)/T))
if(ranf().gt.w) then
  do i=1,100
     x(i)=x(i)*box/boxn
     y(i)=y(i)*box/boxn
     z(i)=z(i)*box/boxn
  enddo
else
  box=boxn
endif
return
end


subroutine energy(e)
e=0.0
do i=1,100
  do j=1,100
     if(j.ne.i) then
       r=sqrt((x(i)-x(j))**2+(y(i)-y(j))**2+(z(i)-z(j))**2)
       r=abs(r-box*nint(r/box))
       e=e+4.*((1.0/r)**12-(1.0/r)**6)
     endif
  enddo
enddo
return
end

回复列表 (共1个回复)

沙发

问题1,

T 是一个 Real,不要用 Real 变量做为循环变量。

Do T = 1 , 100

为什么呢?我们知道,Real 变量判断是否 == 100 是不可靠的。因此,最好不使用 real 作为循环变量。

如果真的期望这么做。

可以这样:
[quote]Integer itemp
Do itemp = 1 , 100
  T = itemp * 1.0
  ...
[/quote]

问题2

if(abs(pold-pnew).lt.0.1)then
      goto loop      
      endif 

这里的 goto loop 跳出了循环外。编译器不允许这样。

goto 最好是不用,不得不用时,也最好在同一层循环内。

实际上,你的这个写法完全可以是:

if(abs(pold-pnew).lt.0.1) Exit

我来回复

您尚未登录,请登录后再回复。点此登录或注册