在过去的几天里,我的FORTRAN代码中遇到了一个非常奇怪的问题,它代表了一个化学网络解算器。
我有一个文本文件,其中包含以下结构作为模型输入的一部分
! Chemistry Scheme from Lellouch et al. (2012)
! Modified 13-06-2016. For more info see "Introduccion de quimica en el codigo de transpote vertical 1D II", pp 20-28
1 ! number of reactions. Do not forget to update
! H + H2O --> OH + H2; R001
'M1006--0701' ! Descriptor
7.5e-16 ! proportionality constant A, sec^-1, cm^-3 sec^-1, cm^-6 sec^-1
-1.6 ! fitting parameter n
-80.81208 ! Activation energy (KJ/mol)
' '
' '
'end'
随着越来越多的反应被卷入其中,它们只是被另一个堆叠在另一个旁边,用''分隔,并且“反应次数”的整数用其数字更新。
我一直在使用这种结构一年,它从来没有给我带来任何问题。最近我用>增加了这样的网络。 50个反应(确切的数字不是很重要,我将解释),然后这个错误显示在我的终端上。
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7F4C0DB72777
#1 0x7F4C0DB72D7E
#2 0x7F4C0D4C4CAF
#3 0x41D3FB in __subroutines_MOD_klosses
#4 0x44B768 in __iteration_MOD_losses
#5 0x44DEBE in __iteration_MOD_updating
#6 0x44DD60 in __iteration_MOD_solving
#7 0x44E0A1 in __iteration_MOD_iterating
#8 0x4014B7 in MAIN__ at temporalDiffusion1.1v.f:?
Segmentation fault (core dumped)
我在FORTRAN的经验告诉我,存储信息的索引和数组存在问题。自从用于分发化学信息的子程序以来,有一些看似合理的东西是“混乱的”,因为有很多字符串处理,在FORTRAN中我总觉得它有点麻烦。
但是在密集检查代码之后,我发现在一些数组操作之后,索引会突然改变,这不应该包含更大的问题。下面是一个如何在终端上打印索引时奇怪地修改索引的示例
before : 11 10 M1310--14 1
after : 11 10 M1310--14 1
------
before : 14 10 M1810--16 0
after : 14 10 M1810--16 0
最右边的整数表示将用作另一个数组的索引的数字。因为在FORTRAN中这些整数从1开始,所以我有这个奇怪的错误。接下来,在先前的打印中涉及的代码片段
print*, "before :", lpTerms(molIndex)%losIndM(i),
* molIndex, theDecRates(Mindex)%label,
* lpTerms(10)%losIndK(1)
lpTerms(molIndex)%losTermsM(i,:) =
* theDecRates(Mindex)%cM(:)*nProfile(:)
print*, "after :", lpTerms(molIndex)%losIndM(i),
* molIndex, theDecRates(Mindex)%label,
* lpTerms(10)%losIndK(1)
如你所见,这是一个基本的乘法,甚至没有涉及突然修改的整数。此外,在错误爬行之前会有一定的迭代次数,所以这不是一个直接的问题。
最奇怪的是,如果化学网络“小”,这完全没被注意到。基本上最后一个陈述并不完全准确,有时候我可以运行51个反应,有些则可以运行50个。删除时的特殊反应似乎不是解决方案。
我使用gfortran编译代码。
这里发生了什么?
非常感谢你,如果你已经阅读了这个问题的结尾!。