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