我写的代码有问题,我试着解释一下我的程序应该做什么。
它从文件(.dat
)读取数据,特别是小时数,风速,温度和潜在温度增量。然后它应该在子例程PBL_6
中详细说明这些数据,这些子例程调用子例程LOG_FIT
和LIN_FIT
线性化半对数函数y = a*ln(x) + b
,其中y
是风速或潜在的温度,x
是测量的高度。
我在代码中定义了不同的数组,一个用于高度(我知道这个数组的所有值),一个用于风速(我有6个风速测量值(u
),每个都用于每个高度),一个用于温度(代码中为T
或tk
),另一个用于增量(dt
)。该算法是一个简单的迭代,从初始条件开始(在PBL_6
而不是在循环do
中),它应该返回u*
,T*
和{的值{1}},然后我在方程式中使用这些值进行循环,以找到新的L
,u*
和T*
。
当循环到达L
的收敛时(循环结束时的条件),循环将停止。我认为我的程序是正确的并且编译,但在运行时L
收到:U
Segmentation Fault Core dumped
我不是Fortran的专家,因此如果您使用简单的术语,我将不胜感激。
我试着说弗拉基米尔,但我现在有很多警告:
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
我该如何解决?我试图初始化nmax,但在运行时它给了我
Warning: Nonconforming tab character at (1)
这是输入文件的示例
Error: Segmentation Fault, core dumped
我使用了你的建议,你可以在这里看到,但我没有关于错误的信息
alessio @ alessio-HP-655-Notebook-PC:〜/ alessio / profili $ gfortran profnew.f90 -fcheck = all -Wall -g -fbacktrace profnew.f90:165.1:
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
和其他警告,现在我尝试初始化N并检查数组x
答案 0 :(得分:2)
如果您真的使用我的建议并编译为
gfortran segf.f90 -fcheck=all -Wall -g -fbacktrace
发生错误时,你会得到一个合适的backtrace:
#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_fit
中的124处看到错误:
xl = alog(x)
其中x
是数组伪参数
real, dimension(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代码中使用TAB。始终使用空格进行缩进。