针对ansys的linux中的分段错误 [英] segmentation error in linux for ansys

查看:170
本文介绍了针对ansys的linux中的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个使用Fortran的用户子程序(Intel Composer(2011.1.107)),用于ANSYS14.5.7
我编辑了代码,将一些数据写入外部顺序文件,并将它们读入数组进行计算如下:

  c将数组元素写入相关元素ID文件和集成点
Do ElementNo = 1,MaxEleNo
c写入相关元素的文件名
write(filename1,'(Element_,I4)')ElementNo
c打开元素数据的相关文件
OPEN(unit = ElementNo,status ='unknown',ACCESS ='APPEND'
&,file = filename1)
Write(ElementNo,fmt ='(*(D))')(sthistory(ElementNo,:) )
close(ElementNo)
end do
sthistory = ZERO
else
endif

当我运行这个时,我从HPC系统得到这个错误:

  Lyra: Ansys(v14.5.7)加载。 
Lyra:Intel Composer(2011.1.107)模块已加载。
/ pkg / suse11 / ansys / v145 / ansys / bin / ansys145:第817行:50102分段错误/pkg/suse11/ansys/v145/ansys/bin/linx64/ansys.e145 -np 4

但是当我在子例程中使用具有save属性的静态数组运行代码时没有问题。但是,在我的计算中保存所有数据并不足够。
有人可以帮我找到可能的问题。

解决方案

低单位数通常保留为特殊单位,如 STDOUT STDERR STDIN 。不要使用这些(除非你知道你在做什么),否则会发生意想不到的事情。我轻度地意识到单位数字有一些上限,但目前我找不到参考。

所以解决你的问题最简单的方法是给单元添加一个偏移量(这又会导致大数组的问题),或者使用 newunit = 如果你的编译器支持它的话。
但是因为你关闭了循环体末尾的文件,所以不要使用像 1234 这样的固定数字。



但是你的代码有更多的问题:

  write(filename1,'(Element_,I4)')ElementNo 

会导致问题大多数编译器)。



考虑这个简单的程序:

 程序测试
write(*,'(Element_,I4)')1
write(*,'(Element_,I4)')10
write(*,'(Element_,I4) ')100
write(*,'(Element_,I4)')1000
write(*,'(Element_,I4)')10000
结束程序

输出结果为:

  Element_ 1 
Element_ 10
Element_ 100
Element_1000
元素_ ****

这导致包含空格的文件名。这可能会导致错误!你可以做的是通过使用'(Element_,I4.4)'来更改格式说明符以使用固定长度,这会给你:

  Element_0001 
Element_0010
Element_0100
Element_1000
元素_ ****

您可以看到,四位数字仍然太小而无法容纳较大的元素,但没有空格。



最后,如果您希望数字直接在斜杠后面开头,而不是前导零,您可以使用 adjustl() trim()

 程序测试
字符(len = 32):: filename

write(filename,'(I4)')1
filename =Element_// adjustl(trim(filename))
write(*,'(a)')filename
write(filename,'(I4)')10
filename =Element_// adjustl(trim(filename))
write(*,'(a)')filename
write(filename,'(I4)')100
filename =Element_// adjustl(trim(filename))
write *,'(a)')文件名
结束程序

结果

  Element_1 
Element_10
Element_100


I am writting a usersubroutine using Fortran (Intel Composer (2011.1.107)) for ANSYS14.5.7 I have edited the code to write some data into an external sequential file and read them to an array for calculations as follows:

c Writes the array elements into the relevent elementID file and Integration point
   Do ElementNo=1,MaxEleNo
c writes the file name for the relevent element
   write (filename1, '( "Element_", I4)' )  ElementNo 
c opens the relevent file for the element data  
   OPEN(unit=ElementNo,status='unknown',ACCESS='APPEND'
 & ,file=filename1)    
   Write(ElementNo,fmt='(*(D))')(sthistory(ElementNo,:))
   close (ElementNo)
  end do
  sthistory=ZERO
  else
  endif

When I run this I get this error from the HPC system:

Lyra: Ansys (v14.5.7) loaded.
Lyra: Intel Composer (2011.1.107) module loaded.
/pkg/suse11/ansys/v145/ansys/bin/ansys145: line 817: 50102 Segmentation fault           /pkg/suse11/ansys/v145/ansys/bin/linx64/ansys.e145 -np 4

But no problem with the code when I run with a static array with save attribute in the subroutine. But this is not suffiecient to hold all the data in my calculations. Can someone help me to find what can be the prob.

解决方案

Low unit numbers are typically reserved for "special units" like STDOUT, STDERR, STDIN. Do not use these (unless you know what you are doing), or something unexpected might happen. I'm mildly aware that there is some upper limit for unit numbers, but I can't find a reference at the moment.

So the easiest way to solve your problem would be to add an offset to the unit (which again would lead to problems for large arrays), or use newunit= if your compiler supports it. But since you close the files at the end of the loop body, way not use a fixed number like 1234?

But you have more issues with your code: The line

write (filename1, '( "Element_", I4)' )  ElementNo

will lead to problems (for most compilers).

Consider this simple program:

program test
  write (*, '( "Element_", I4)' )  1
  write (*, '( "Element_", I4)' )  10
  write (*, '( "Element_", I4)' )  100
  write (*, '( "Element_", I4)' )  1000
  write (*, '( "Element_", I4)' )  10000
end program

The output is:

Element_   1
Element_  10
Element_ 100
Element_1000
Element_****

Which leads to a file name that contains spaces. This might lead to an error! What you could do is change the format specifier to use a fixed length by using '( "Element_", I4.4)', which would give you:

Element_0001
Element_0010
Element_0100
Element_1000
Element_****

You can see that four digits is still too small to hold the larger elements, but no spaces any more.

Finally, if you wanted the numbers to start after the slash directly without the leading zeros you could use a combination of adjustl() and trim():

program test
  character(len=32)  :: filename

  write (filename, '(I4)')  1
  filename = "Element_" // adjustl(trim(filename))
  write(*,'(a)') filename
  write (filename, '(I4)')  10
  filename = "Element_" // adjustl(trim(filename))
  write(*,'(a)') filename
  write (filename, '(I4)')  100
  filename = "Element_" // adjustl(trim(filename))
  write(*,'(a)') filename
end program

results in

Element_1                       
Element_10                      
Element_100  

这篇关于针对ansys的linux中的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆