关于程序不进入循环的问题
大家好,我之前在论坛问过关于调用子程序输出全为0的问题,在论坛中热心朋友的帮助下已经解决现在我在进行导热问题数值计算的过程中又遇到了新的问题
程序的目的就是一片L型的区域离散化,然后每个点设定一个初值,不断迭代求解方程,当误差小于一定值时输出
外边界点温度固定为30,内边界点固定为10,L型内部点设置初值为10,输出结果发现好像程序没有进行循环过程。
上次解决了的问题代码已经被我注释掉,这次不知道是哪里有问题,希望朋友们帮忙解答一下,谢谢大家!
PROGRAM BCI
IMPLICIT NONE
INTEGER::T1=10
INTEGER::T2=30
INTEGER::M,N
REAL::T(16,12)
REAL::TA(16,12)
REAL::ET(16,12)
REAL::LAN=0.53
REAL::ERR
CALL GRID
CALL START
OPEN(01,FILE='BCI.dat')
DO WHILE(ERR>0.00000001)
CALL SOLVER
END DO
PRINT*,' M N T'
DO M=1,16
DO N=1,12
PRINT*,M,N,T(M,N)
WRITE(01,*)M,N,T(M,N)
END DO
END DO
CONTAINS
SUBROUTINE GRID
INTEGER::T1=10
INTEGER::T2=30
INTEGER M,N
!REAL T(16,12)
DO N=1,7
T(6,N)=T1
END DO
DO M=7,16
T(M,7)=T1
END DO
DO N=1,12
T(1,N)=T2
END DO
DO M=2,16
T(M,12)=T2
END DO
END SUBROUTINE GRID
SUBROUTINE START
INTEGER M,N
!REAL T(16,12)
DO M=2,5
DO N=1,11
T(M,N)=10
END DO
END DO
DO M=6,16
DO N=8,11
T(M,N)=10
END DO
END DO
END SUBROUTINE START
SUBROUTINE SOLVER
INTEGER::T1=10
INTEGER::T2=30
INTEGER::M,N
!REAL::T(16,12)
!REAL::TA(16,12)
!REAL::ET(16,12)
!REAL::ERR
DO M=2,5
TA(M,1)=0.25*(2*T(M,2)+T(M-1,1)+T(M+1,1))
END DO
DO M=2,5
DO N=2,11
TA(M,N)=0.25*(T(M+1,N)+T(M-1,N)+T(M,N+1)+T(M,N-1))
END DO
END DO
DO M=6,15
DO N=8,11
TA(M,N)=0.25*(T(M+1,N)+T(M-1,N)+T(M,N+1)+T(M,N-1))
END DO
END DO
DO N=8,11
TA(16,N)=0.25*(2*T(15,N)+T(16,N-1)+T(16,N-1))
END DO
DO N=1,7
TA(6,N)=T1
END DO
DO M=7,16
TA(M,7)=T1
END DO
DO N=1,12
TA(1,N)=T2
END DO
DO M=2,16
TA(M,12)=T2
END DO
DO M=1,16
DO N=1,12
ET(M,N)=ABS(TA(M,N)-T(M,N))
END DO
END DO
ERR=MAXVAL(ET(1:16,1:12))
DO M=1,16
DO N=1,12
T(M,N)=TA(M,N)
END DO
END DO
END SUBROUTINE SOLVER
END PROGRAM BCI
本帖最后由 kyra 于 2017-10-24 08:52 编辑
昨天我就忍着你,发代码截图干嘛?
第一,别人不能复制粘贴,想帮你调试代码,就得照着图片重新打一遍代码。试问几个人有这耐心?
第二,浪费论坛资源,浪费浏览者的流量。
第三,自己还麻烦。
为啥不直接复制粘贴呢?
最后,给你介绍一个很好的检查错误方法,叫单步调试:
http://v.fcode.cn/video-debugger.html
http://debug.w.fcode.cn
各位不好意思,新人不太知道规矩。。
以前遇到过复制代码格式全部错乱的情况。
现已将代码复制过来,还烦请各位帮忙看下,谢谢大家! 本帖最后由 kyra 于 2017-10-24 11:16 编辑
你试试对
REAL::T(16,12)
REAL::TA(16,12)
REAL::ET(16,12)
这三个数组进行初始化
也就是
REAL::T(16,12)= 0
REAL::TA(16,12)= 0
REAL::ET(16,12)= 0
此外,你可以学习一下数组整体操作和数组片段,可以省很多代码,例如
DO N=1,7
T(6,N)=T1
END DO
可以简写为
T(6,1:7) = T1
再例如
DO M=2,5
DO N=1,11
T(M,N)=10
END DO
END DO
可以简写为
T(2:5,1:11) = 10
而
DO M=1,16
DO N=1,12
ET(M,N)=ABS(TA(M,N)-T(M,N))
END DO
END DO
则可以简写为
ET = abs( TA - T )
谢谢您对代码简化的建议!
不过初始化过后还是不行,跟之前的结果一样,没有循环。输出结果还是初值。 你用的什么编译器?这是我修改后的输出。(我没仔细看对不对,反正有变化了)
我用的VS2015集成Intel ParallelStudio XE 2018编写的
话说您这是什么编译器? 我用的gfortran,想起来了,你的 err 是不是也没初始化? ERR初始化以后也不行。
我把改后的代码发上来,您看看是不是我改得不对呀?
我再下一个gfortran看看
PROGRAM BCI
IMPLICIT NONE
INTEGER::T1=10
INTEGER::T2=30
INTEGER::M,N
REAL::T(16,12)=0
REAL::TA(16,12)=0
REAL::ET(16,12)=0
REAL::LAN=0.53
REAL::ERR=0
CALL GRID
CALL START
OPEN(01,FILE='BCI.dat')
DO WHILE(ERR>0.00000001)
CALL SOLVER
END DO
PRINT*,' M N T'
DO M=1,16
DO N=1,12
PRINT*,M,N,T(M,N)
WRITE(01,*)M,N,T(M,N)
END DO
END DO
CONTAINS
SUBROUTINE GRID
!INTEGER::T1=10
!INTEGER::T2=30
INTEGER M,N
T(6,1:7) = T1
T(7:16,7)=T1
T(1,1:12)=T2
T(2:16,12)=T2
END SUBROUTINE GRID
SUBROUTINE START
INTEGER M,N
T(2:5,1:11)=10
T(6:16,8:11)=10
END SUBROUTINE START
SUBROUTINE SOLVER
!INTEGER::T1=10
!INTEGER::T2=30
INTEGER::M,N
DO M=2,5
TA(M,1)=0.25*(2*T(M,2)+T(M-1,1)+T(M+1,1))
END DO
DO M=2,5
DO N=2,11
TA(M,N)=0.25*(T(M+1,N)+T(M-1,N)+T(M,N+1)+T(M,N-1))
END DO
END DO
DO M=6,15
DO N=8,11
TA(M,N)=0.25*(T(M+1,N)+T(M-1,N)+T(M,N+1)+T(M,N-1))
END DO
END DO
DO N=8,11
TA(16,N)=0.25*(2*T(15,N)+T(16,N-1)+T(16,N-1))
END DO
ET=ABS(TA-T)
ERR=MAXVAL(ET(1:16,1:12))
T=TA
END SUBROUTINE SOLVER
END PROGRAM BCI err 不能初始化为0呀,不然肯定不进入循环。
第一次判断就没有误差了,就不需要进入循环计算了。
REAL::ERR=999.0 试试
页:
[1]
2