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。