Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

MSC.Marc Subroutine

Reza_M_
Beginner
1,833 Views

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

0 Kudos
17 Replies
andrew_4619
Honored Contributor II
1,833 Views

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  

0 Kudos
mecej4
Honored Contributor III
1,833 Views

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.

0 Kudos
Reza_M_
Beginner
1,833 Views

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

 

0 Kudos
mecej4
Honored Contributor III
1,833 Views

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.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,833 Views

stnod_d((lnode(1)-1)

So if Inode(1) is 1, what index are you using for stnod_d?

Jim Dempsey
 

0 Kudos
andrew_4619
Honored Contributor II
1,833 Views

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.

0 Kudos
mecej4
Honored Contributor III
1,833 Views

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.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,833 Views

I guess I have to clean my glasses, saw ) in wrong spot.

You could enable array bounds checking too.

Jim

0 Kudos
Reza_M_
Beginner
1,833 Views

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

 

 

0 Kudos
andrew_4619
Honored Contributor II
1,833 Views

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.

 

0 Kudos
mecej4
Honored Contributor III
1,833 Views

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

 

0 Kudos
andrew_4619
Honored Contributor II
1,833 Views

@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?

 

0 Kudos
mecej4
Honored Contributor III
1,833 Views

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.

0 Kudos
andrew_4619
Honored Contributor II
1,833 Views

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...

 

 

0 Kudos
Reza_M_
Beginner
1,833 Views

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

0 Kudos
andrew_4619
Honored Contributor II
1,833 Views

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.

 

0 Kudos
John_Campbell
New Contributor II
1,833 Views

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
 

0 Kudos
Reply