- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I wrote the following subroutine to extract nodal stress values. It perfectly writes down the nodal stresses in MSC.Marc installed for Linux; however, when I try to implement this subroutine in MSC.Marc installed for Windows using intel(R) Visual Fortran compiler, error "forrt1: severe <157>: Program Exception - access violation" occurs.
The subroutine is:
subroutine impd(lnode,dd,td,xord,stnod,f,v,a)
include '../common/implicit'
include '../common/array3'
include '../common/array2'
include '../common/spacevec'
include '../common/strvar'
include '../common/concom'
include '../common/elmcom'
include '../common/dimen'
integer j
character NodeStress*90
dimension lnode(2)
dimension dd(ndeg),td(ndeg),xord(ncrd),f(ndeg),
*v(ndeg),a(ndeg)
310 format(I4,(1H:),6E14.6)
if(lnode(2).ne.1) return
if(lnode(1).eq.1) then
write(NodeStress,'(a,i4.4,a,$)') './NodalStress_',inc,'.dat'
open(unit = inc+1000 ,file=NodeStress,status="new")
c if(lnode(1).eq.1) then
write(inc+1000,'(17Hlabel=NodalStress)')
write(inc+1000,'(13Hnum_item=3800,/)')
end if
open(inc+1000)
write(inc+1000,310) lnode(1)-1,(stnod_d((lnode(1)-1)*6+j),
+j=1,6)
return
end
I would appreciate if you could help me to figure out the problem.
Kind Regards,
APPa
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So where is inc given a value? With some compiler options it will be initialised to zero, with others uninitialised variables have random junk,
I would also change the Marc script(s) that compiles the source to add some checking options /traceback would be good as it would give info on what line in the Fortran it fails at
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is a lot of information missing. The subroutine is short, but contains a number of INCLUDE statements and you (Reza M.) have not told us what those included files contain. Probably, few of us are users of Marc.
As app4619 told you, you should try to obtain the line number of the statement that caused the access violation by compiling with traceback enabled. The value of 'inc' should be proper in order for the unit numbers in the I/O statements to be acceptable. The value of lnode(1) should be such that the subscript of stnod_d in the last WRITE statement is within bounds.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Greetings App4619 and mecej4,
Thank you for your reply. I found the following line causes access violation:
write(inc+1000,310) lnode(1)-1,(stnod_d((lnode(1)-1)*6+j),
+j=1,6)
lnode(1) is the node number changing from 1 to 3800 in this case. stnod_d is a variable given in common block "spacevec" which has been included in line 5 of the subroutine. stnod_d will write down the stress tensor having 6 components.
The subroutine "impd" is called once per each increment and "inc" is the increment number. I am sure that the problem does not arise from "inc" initialization because all subroutines in Marc recognize increment number.
Could you please let me know how I should realize whether stnod_d in the last WRITE statement is within bounds or not?
Kind Regards,
Reza
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If Inode(1) ranges from 1 to 3800, the subscript of stnod_d will range from 1 to 22800. What is the declared size of the array stnod_d in the common block spacevec? Is the upper bound at least 22800?
Are the variables of type REAL, arguments as well as common block members, declared REAL*8 or REAL*4, whichever MARC requires?
You have to appreciate that I know nothing about what Marc does to variables, so I have to check that anything passed to your subroutine, either through the argument list or common blocks, has correct values. App4619's point is that the variable inc is not in the argument list and, therefore, if it is not in one of the common blocks, it is a local variable. If so, you are using it with an undefined value in expressions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
stnod_d((lnode(1)-1)
So if Inode(1) is 1, what index are you using for stnod_d?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you could try
i_chk_tmp_var=(lnode(1)-1)*6+j) if(i_chk_tmp_var < 1 .or. i_chk_tmp_var > ??????) then ! ???? is declared size of stnod_d write(*,*) i_chk_tmp_var, j, lnode(1) endif
You should declare local integer :: i_chk_tmp_var
It will then give you the values to std output prior to a bound exceed which might give some clues.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
stnod_d((lnode(1)-1)So if Inode(1) is 1, what index are you using for stnod_d?
The index he uses is (lnode(1)-1)*6+j, j = 1..6, so there should be no problem with lnode(1) = 1.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I guess I have to clean my glasses, saw ) in wrong spot.
You could enable array bounds checking too.
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your replies.
"inc" is increment number and it is not a local variable. "inc" It is available through " include '../common/concom' ".
Marc is written completely in double precision. Hence, on all machines, an IMPLICIT REAL *8 (A-H, O-Z) statement is required in the user subroutines. This is to ensure that variables passed between Marc and the user subroutine are compatible and to ensure that any common blocks included are correct.
lnode(1) ranges from 1 to 3706 in this case. I followed app4619's comment and I found that "i_chk_tmp_var" ranges from 0 to 22230 with the step of 6 while j=0. I uploaded common block "spacevec". Please do let me know how the size of array "stnod_d" should be declared in "spacevec"?
Kind Regards,
Reza
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In spacevec we have:
real*8 esnod_d,wtnod_d,stnod_d pointer (pstnod_d,stnod_d(*))
I am not familiar with this type of pointer statement/ declaration however I think that is referring to a deferred shape array, ie one the is sized dynamically at run time with an ALLOCATE. Perhaps someone else can comment.
You could write out UBOUND(stnod_d) and LBOUND(stnod_d) which will give the upper and lower bounds of the array normally in fortran the lower bound is by default 1 unless specifically declared otherwise so I am guessing that the zero value is the one that causes the error.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are numerous occurrences of Cray pointers in the declarations of SPACEVEC, so anything is possible as to what MARC does with those pointers.
I don't think that the Fortran runtime can provide information about arrays that were allocated outside its view. Nor can you find out about the bounds/size of Cray pointee arrays using UBOUND() and SIZE(), and array bounds checking cannot reveal bounds violations in Cray pointee arrays. These are all reasons for not using Cray pointers, now that Fortran provides other mechanisms for dynamic memory allocation. However, if MARC requires that you use Cray pointers, you are stuck with them.
If you are not aware of Cray pointers, here is a short example:
program crayptr implicit none ! integer a(10),i do i=1,10 a(i)=i*i-3 end do call sub(a) end program subroutine sub(a) implicit none integer a(10),i,b(2:*) pointer (pb,b) ! pb=loc(a(6)) do i=2,6 write(*,*)i,a(4+i),b(i) end do return end subroutine
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@mecej4. I get the Cray pointers but what I didn't get was declaring a scaler fred and then pointing at fred(*) where fred is not even a dummy arg. The examples in the ifort help shows pointing at fred(:) or fred(:,:) where fred is this implied as allocatable. It is fairly academic as I would not use this extension I am assuming the fred(*) is just a extension variation on the implied allocatable syntax?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see "fred" anywhere in this thread or in the IFort documentation, so I don't quite understand the allusions. The IFort documentation contains the following relevant rules:
- A pointee array can have fixed, adjustable, or assumed dimensions
- A pointee is not allocated any storage
Thus, dimensions shown in the declaration of a pointee are only for the compiler's use, probably for address calculations. Only after the corresponding integer pointer is given a valid value can the scalar or array pointee be used, with subscripts if appropriate. The notion of "allocatable" probably did not exist in Fortran when Cray pointers were invented.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I fred was just a random meaningless variable name used as an example (fred and bill are my favourites for this purpose for some reason). I guess the (*) just indicates it is pointing at an array of some unknown size under the assumed dimensions clause. I'm surprised the compiler accepts this but we are looking at language extensions I suppose...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
LBOUND(stnod_d) gives me 1 while program is unable to show the upper bound by using UBOUND(stnod_d). I wonder how I should realize whether the problem comes from zero value when lnode(1) is equal 1?
Another question is that why Marc in Linux does not show this error?
Kind Regards,
Reza
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do the output of i_chk_tmp_var every time and the last value output is the one that causes the crash on the line we are looking at. How you solve the problem is another matter. I would presume the user routine logic is flawed and needs debugging. I can't really help there not knowing what it is meant to do and also what MSc Marc needs. It did in the past use Marc for large displacement non-linear analysis of "rubber" parts but I never used user subroutines.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can subroutine impd be called with lnode(1) = 0 ? ie a node with no stress.
If it is not working, then write some tests to see what value is being provided.
I am also not familiar with " open(inc+1000)". This is not allowed in the Fortran I use.
John
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page