Segmentation fault Fortran 90中转储的分段故障核
我写的代码有问题,我试图解释我的程序应该做什么。 它从文件(Segmentation fault Fortran 90中转储的分段故障核,segmentation-fault,fortran,Segmentation Fault,Fortran,我写的代码有问题,我试图解释我的程序应该做什么。 它从文件(.dat)中读取数据,特别是小时、风速、温度和潜在温度增量的值。然后它应该在子程序PBL_6中详细说明这些数据,该子程序调用子程序LOG_FIT和LIN_FIT将半对数函数y=a*ln(x)+b线性化,其中y是风速或潜在温度,x是测量高度 我在代码中定义了不同的数组,一个用于高度(我知道该数组的所有值),一个用于风速(我有6个风速测量值(u),每个高度),一个用于温度(T或tk,在代码中),一个用于增量(dt)。该算法是一个简单的迭代,
.dat
)中读取数据,特别是小时、风速、温度和潜在温度增量的值。然后它应该在子程序PBL_6
中详细说明这些数据,该子程序调用子程序LOG_FIT
和LIN_FIT
将半对数函数y=a*ln(x)+b
线性化,其中y
是风速或潜在温度,x
是测量高度
我在代码中定义了不同的数组,一个用于高度(我知道该数组的所有值),一个用于风速(我有6个风速测量值(u
),每个高度),一个用于温度(T
或tk
,在代码中),一个用于增量(dt
)。该算法是一个简单的迭代,从初始条件开始(在PBL_6
不在循环中do
),它应该返回u*
、T*
和L
,然后我用方程中的这些值进行循环,以找到新的u*
、T*
和L
当达到L
的收敛点时,循环将停止(循环结束时的条件)。我认为我的程序是正确的,它可以编译,但在运行时U
receive:Segmentation Fault Core dumped
program profile
implicit none
character(len=12) filein,fileout
real, dimension(6) :: u
real, dimension(6) :: z=(/0.5,1.,2.,4.,8.,16./)
real, dimension(2) :: dt,tp
real, parameter :: k = 0.4
real, parameter :: z0 = 0.0012
real :: tk,ustarp, tstarp, tetai, Lp
integer :: ih
integer :: row, i
write(*,'(2x,''File input .......''/)')
read(*,'(a12)') filein
write(*,'(2x,''File output........''/)')
read(*,'(a12)') fileout
open(unit=90,File=fileout)
open(unit=50,File=filein)
write(90,130)
do row = 1,24
read(50,*) ih,(u(i),i=1,6),tk,(dt(i),i=1,2)
tk = tk+273.15
dt(2) = dt(2)+dt(1)
tp(1) = dt(1) + tk
tp(2) = (dt(2)-dt(1)) + tp(1)
call PBL_6(u,tp,z,tk,ustarp,tstarp,Lp)
!write(*,*) tp
write(90,131) ih,ustarp,tstarp,Lp
enddo
130 format(15x, &
'====================================',/,15x, &
' hour ustar tstar L ',/,15x, &
'====================================')
131 format(15x,i5,4x,f7.3,2x,f7.3,2x,f7.0,2x)
close(50)
close(90)
end program profile
subroutine PBL_6(u,tp,z,T,ustarp,tstarp,Lp)
implicit none
integer :: i, j, n
integer :: nmax
real :: a, b, c, d
real, intent(in) :: T
real, intent(out):: ustarp,tstarp,Lp
real, dimension(6),intent(in) :: z
real, dimension(6),intent(in) :: u
real, allocatable, dimension(:) :: uip,tetaip,L
real, dimension(2),intent(in) :: tp
real :: Lo,an,bn,cn,dn,tstar,ustar
real :: g=9.81
real :: epsilon = 0.001
real :: k = 0.4
! First Guess 1/L = 0
CALL LOG_FIT(N,z,u,a,b)
ustar = k*a
CALL LOG_FIT(N,z,u,c,d)
tstar = k*c
Lo = (T*ustar*ustar)/(k*g*tstar )
allocate(uip(nmax),tetaip(nmax),L(nmax))
do i=1,nmax
do j=1,2
L(i) = Lo
! Convective conditions
uip = u - 1 + (1-16*z/L(i))**0.25
tetaip = tp(j) + 2*alog(0.5 + 0.5*(sqrt(1-16*z/L(i))))
CALL LOG_FIT(N,z,uip,an,bn)
ustarp = k*an
CALL LOG_FIT(N,z,tetaip,cn,dn)
tstarp = k*cn
Lp = (T*ustarp*ustarp)/(k*g*tstarp)
if(abs(Lp-L(i)).lt.epsilon) then
write(*,*) Lp
return
endif
enddo
enddo
deallocate(uip,tetaip,L)
end
subroutine LOG_FIT(N,x,y,a,b)
implicit none
integer :: i,N
real, dimension(N) :: x,y
real, dimension(:), allocatable :: xl,yl
real :: a,b
real :: al,bl
allocate(xl(N),yl(N))
xl = alog(x)
yl = y
call LIN_FIT(N,xl,yl,al,bl)
a = al
b = bl
deallocate(xl,yl)
end
subroutine LIN_FIT(N,x,y,a,b)
implicit none
integer :: N,i
real :: Xm, Ym, xx,yy, Sxx, Sxy
real, dimension(N) :: x, y
real :: a,b
! Calculation of linear regression coefficients
Xm = SUM(x)/REAL(N)
Ym = SUM(y)/REAL(N)
SXX = 0.
SXY = 0.
DO i=1,N
xx = x(i)-Xm
yy = y(i)-Ym
SXX = SXX+xx**2
SXY = SXY+xx*yy
Enddo
!Coefficients
a = SXY/SXX
b = Ym - a*Xm
end
我不是Fortran的专家,因此如果您使用简单的术语,我将不胜感激
我试过了,就像你说的弗拉基米尔,但我现在有很多警告:
Warning: Nonconforming tab character at (1)
我怎样才能解决它们?我试图初始化nmax,但在运行时它给了我
Error: Segmentation Fault, core dumped
这是输入文件的一个示例
h u1 u2 u3 u4 u5 u6 T dt1 dt2
0 3.02 3.41 3.83 4.27 4.87 5.75 12.7 0.16 0.20
1 2.73 3.05 3.42 3.85 4.43 5.29 12.5 0.16 0.19
2 2.16 2.45 2.77 3.21 3.88 4.91 11.9 0.17 0.03
3 4.04 4.48 5.00 5.54 6.14 7.05 12.9 0.12 0.15
4 4.02 4.50 5.03 5.58 6.12 6.88 13.0 0.19 0.20
5 2.76 3.12 3.51 4.00 4.62 5.53 12.1 0.24 0.27
6 3.93 4.35 4.88 5.48 6.18 7.13 11.7 0.24 0.26
7 5.30 5.95 6.66 7.36 8.04 8.98 11.9 0.25 0.29
8 3.98 4.44 4.98 5.50 6.10 6.95 11.1 0.19 0.18
9 4.07 4.44 4.97 5.53 6.09 6.84 11.4 0.14 0.13
10 2.77 3.03 3.35 3.71 4.08 4.59 11.6 0.06 0.05
11 3.40 3.77 4.15 4.47 4.72 4.88 14.1 -0.17 -0.20
12 6.13 6.92 7.62 8.31 8.82 9.30 14.5 -0.29 -0.12
13 7.21 8.06 8.89 9.69 10.37 11.04 14.6 -0.30 -0.15
14 7.08 7.86 8.71 9.50 10.13 10.78 15.3 -0.09 -0.07
15 8.56 9.53 10.57 11.49 12.34 13.29 14.6 -0.41 -0.10
16 8.16 9.08 10.07 11.00 11.95 13.02 14.9 -0.15 -0.05
17 7.96 8.88 9.89 10.88 11.76 12.81 13.6 0.12 0.14
18 5.55 6.20 6.92 7.62 8.39 9.31 12.4 0.19 0.18
19 4.49 5.07 5.67 6.28 6.98 7.89 11.1 0.11 0.24
20 4.68 5.25 5.88 6.49 7.19 8.11 10.3 0.26 0.21
21 3.43 3.86 4.34 4.84 5.47 6.41 8.9 0.28 0.20
22 3.62 4.04 4.54 5.08 5.72 6.63 8.4 0.28 0.18
23 4.24 4.67 5.25 5.83 6.49 7.43 7.8 0.11 0.14
正如你在这里看到的,我使用了你的建议,但我没有关于错误的信息
alessio@alessio-HP-655-Notebook-PC:~/alesio/profili$gfortran profnew.f90-fcheck=all-Wall-g-fbacktrace
profnew.f90:165.1:
Xm = SUM(x)/N
1
Warning: Nonconforming tab character at (1)
profnew.f90:166.1:
Ym = SUM(y)/N
1
Warning: Nonconforming tab character at (1)
profnew.f90:168.1:
SXX = 0.
1
Warning: Nonconforming tab character at (1)
profnew.f90:169.1:
SXY = 0.
1
Warning: Nonconforming tab character at (1)
还有其他警告,现在我尝试初始化N并检查数组x,如果您真的使用了我的建议并编译为
gfortran segf.f90 -fcheck=all -Wall -g -fbacktrace
当错误发生时,您将得到一个正确的答案:
#0 0x7FB1D1D306F7
#1 0x7FB1D1D30CC4
#2 0x7FB1D12530DF
#3 0x4024E7 in log_fit_ at segf.f90:124 (discriminator 2)
#4 0x400EC3 in pbl_6_ at segf.f90:74 (discriminator 2)
#5 0x4032CB in profile at segf.f90:34 (discriminator 2)
Neoprávněný přístup do paměti (SIGSEGV)
现在,您可以在步骤log\u fit
中看到124上发生的错误:
xl = alog(x)
其中x
是一个数组伪参数
real,维度(N)::x,y
很可能您传递的数组x
错误
如果您注意我的其他建议,我会告诉您nmax
未在PBL_6
中初始化。另一个未初始化的变量是N
,这非常糟糕
CALL LOG_FIT(N,z,u,a,b)
ustar = k*a
CALL LOG_FIT(N,z,u,c,d)
tstar = k*c
这里,N
没有确定的值,它必须恰好在上面所示的点失败
整个PBL_6对我来说是一团糟。好好想想你想在那里实现什么,价值观应该来自哪里,你想在哪里传递它们
顺便说一句,关于不合格制表符的警告意味着您不应该在任何Fortran代码中使用制表符。始终使用空格进行缩进。没有输入文件,我们无法测试它。您应该首先自己调试它。使用编译器为此提供的选项。尝试
gfortran segf.f90-fcheck=all-Wall-g-fbacktrace
。它在编译时会给出几个警告。例如,nmax
未初始化。请阅读并准备一个我们可以尝试的示例。你真的使用了我以前的建议吗?是的,现在我使用你的建议,但问题仍然是,你说的“例子”是什么意思?我试着只编译主程序并打印T的值,它运行正常,我认为问题出在子程序PBL或LOG_Fit中。例如,我们可以编译并运行它。我们无法运行您的示例,因为我们没有任何数据。给我们举一些数据文件的例子。是否确实使用-g-fbacktrace-fcheck=all
编译了所有内容。此外,请使用包含子例程,使其成为内部子例程,或将其移动到模块中。外部子程序是邪恶的。我在PBL_6中的目标是返回我称之为ustarp、tstarp和Lp的ustar、tstar和L的值,以便在第一次猜测时将它们与相同的值区分开来。在您看来,该子程序中有什么不清楚的地方?n
的含义是什么,maxn
他们应该从哪里得到一些值一点也不清楚。请注意,这里的大多数人不是边界层气象学家,不知道摩擦速度或奥布霍夫长度是多少。我知道,但这对我理解你的代码没有太大帮助。我理解情况,这段代码非常具体,我在第一篇文章中试图解释算法,但我认为不可能解释方程的每个元素。无论如何,nmax将是达到收敛的最大迭代次数。我将其传递给子例程,用nmax替换N。我看到你是大气和气象科学的教授,我可以私下和你联系解释一下算法,也许能找到一个解决方案吗?我不喜欢去私人频道,因为这个网站是为了帮助别人。请注意,您将一个未定义的N传递给log\u fit
,其中它用于定义x
和y
的大小。但是,在PBL_6
中,z
和u
具有恒定的大小6
。你应该考虑N是否应该是6。