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

problem passing arrays from one subroutine to another

guruduttc
Beginner
2,135 Views
Hello,

Mentioned below is a part of a Fortran 90 code to be implemented in a software called abaqus.The important variables have been made bold.
My question is as follows.
I would like to assign the values of COORDS array to V array(v1,v2,v3,v4,v5,v6,v7,v8,v9) and the values of PROPS array to E,ni,H,e31,d33.I then need to pass these values to the dummy arguements in the call Kij statement.

Do i need to make an interface to pass the values or is there any other way of passing the values from one subroutine to another?

**Please note: The values for the arguments in UEL subroutine are passed from an input file*****
**Please note: arguments other than COORDS and PROPS are not important to the present question****


subroutine UEL(RHS,AMATRX,SVARS,ENERGY,NDOFEL,NRHS,NSVARS,&
PROPS,NPROPS,COORDS,MCRD,NNODE,U,DU,V,A,JTYPE,TIME,DTIME,&
KSTEP,KINC,JELEM,PARAMS,NDLOAD,JDLTYP,ADLMAG,PREDEF,NPREDF,&
LFLAGS,MLVARX,DDLMAG,MDLOAD,PNEWDT,JPROPS,NJPROP,PERIOD)


implicit none
real*8::NSVARS,NPROPS,MCRD,NNODE,JTYPE,DTIME,KSTEP,KINC,JELEM,NDLOAD,NPREDF,MLVARX,&
PNEWDT,NJPROP,PERIOD,NDOFEL,NRHS,MDLOAD
real*8:: RHS(MLVARX,*),AMATRX(NDOFEL,NDOFEL),PROPS(*),& ***PROPS=5*****
SVARS(*),ENERGY(8),COORDS(MCRD,NNODE),U(NDOFEL),& ***MCRD=3 and NNODE=9***
DU(MLVARX,*),V(NDOFEL),A(NDOFEL),TIME(2),PARAMS(*),&
JDLTYP(MDLOAD,*),ADLMAG(MDLOAD,*),DDLMAG(MDLOAD,*),&
PREDEF(2,NPREDF,NNODE),LFLAGS(*),JPROPS(*),SRESID(72)

real*8::E,ni,H,detJ,e31,d33
real*8:: v1(3),v2(3),v3(3),v4(3),v5(3),v6(3),v7(3),v8(3),v9(3)


do i=1,MCRD
v1(i)=COORDS(i,1)
v2(i)=COORDS(i,2)
v3(i)=COORDS(i,3)
v4(i)=COORDS(i,4)
v5(i)=COORDS(i,5)
v6(i)=COORDS(i,6)
v7(i)=COORDS(i,7)
v8(i)=COORDS(i,8)
v9(i)=COORDS(i,9)
enddo
E=PROPS(1)
ni=PROPS(2)
H=PROPS(3)
e31=PROPS(4)
d33=PROPS(5)




call Kij (v1, v2, v3, v4,v5,v6,v7,v8,v9, H, E, ni, e31,d33,&
KM11,KM12,KM13,KM14,KM15,KM16,KM17,KM18,KM19,KM22,KM23,KM24,KM25,KM26, &
KM27,KM28,KM29,KM33,KM34,KM35,KM36,KM37,KM38,KM39,KM44,KM45,KM46, &
KM47,KM48,KM49,KM55,KM56,KM57,KM58,KM59,KM66,KM67,KM68,KM69, &
...........................................................*not important for the question*....)


0 Kudos
1 Solution
Greg_T_
Valued Contributor I
2,135 Views
Hello,

I would recommend testing taking advantage of Intel Fortran (IVF)and Visual Studio (VS)if possible, outside of the Abaqus analysis, for inital testing and debugging. I recommend writing a main program that can run the user subroutine so that testing can be done entirely within VS, or by IVF from the command line. Perhaps you could write the allvalues passed into the user subroutine from Abaqus to the *.msg file for just one element (a single element mesh), which would give you the values the main testing program would duplicate in the stand-alone test. Then you can run the single element with the user subroutine by itself entirely within IVF and VS to see if it is working as expected and take advantage of the debugging tools if that would help. I suppose this approach is within the category of general Fortran debugging and testing and may be obvious. But perhaps this way would allow you to check the problem of the passed values and local arrays. This method has helped me in the past. Then once the stand-alonetest is working, return to Abaqus and check that the same single element test works there too. Hopefully writing all the values to the *.msg file and comparing to the debugging output from the testing in VS, something won't match andwill help reveal the cause of the array and value problem.

If a problem remains, then the single element mesh will also be a good example to submit to the Abaqus technical support for advice.

On a side note, I was suprised to see my previous post in a different color. I don't think I selected another option that would cause that, and it hasn't happened for other posts. Is there an editing option I should change?

Regards,
Greg

View solution in original post

0 Kudos
11 Replies
TimP
Honored Contributor III
2,135 Views
Doesn't Abaqus provide sample calling sequences? This forum can't substitute for software vendor support.
There is no problem using Fortran 77 calling standard along with Fortran 90 code, if that is your question. It's your choice whether to create interface blocks, if the vendor doesn't provide them as an alternative.
0 Kudos
guruduttc
Beginner
2,134 Views
Hello,

My question is entirely related to Fortran programming.I might have given badly named tittle to the thread. I thought it would be better to mention Abaqus as it would make things clear as to what the code is meant for.

Now,coming back to my question.If I need to pass the arrays from one subroutine to another,like from the Subroutine UEL to subroutine Kij in my example,would the code which I have posted work, or do I need to make an interface to pass the values.?.Sorry if it is a very basic question.


I need to pass values of v1,v2,v3,v4,v5,v6,v7,v8,v9 arrays which get their values from COORDS array to the Kij subroutine through the call statement.

0 Kudos
mecej4
Honored Contributor III
2,135 Views
You are better off in this forum if your questions are framed in terms of using the Intel compiler and, by stretching that context, in terms of the Fortran language. By making your post appear specific to a third party package (Abaqus), you incur the disadvantage that there are too few respondents here who use that package.

The code that you showed is really F77 code written in free-format, with a few double colons thrown in. Remove those double colons and start statements in column-7 and your code is just plain F77.

Interfaces are never necessary for F77 code. In fact, interfaces were not part of the Fortran-77 standard. However, without an explicit interface the compiler had to assume that the user called external subroutines and referenced external functions with the correct number and types of arguments, i.e., that the implicit interface was correct. Many F77 compilers provided explicit interfaces as a feature to catch errors in such calls and references. With a program that can be compiled and run successfully, removing any interface blocks in the code will have no effect.

For example, the following program has one bug. Since the interface block is present, the compiler tells you that line-8 has a function call with an incorrect argument. Once you replace '2' by '2.0', the program works correctly, with or without the interface block.

[fortran]program tst
interface
real function sqr(x)
real, intent(in) :: x
end function sqr
end interface
real :: x
x=sqr(2)
write(*,*)x
end program tst

real function sqr(x)
real :: x
sqr = x*x
return
end function sqr
[/fortran]


If you meant to ask about the broader topic of how to pass variables, the usual answers are well covered in text-books and Fortran manuals: you can use function/subroutine arguments, common blocks, temporary files, alternate returns, and, in Fortrn 90 and beyond, through modules. In archeological times, SENSE LIGHTs were available. Take your pick, keeping in mind any restrictions imposed by Abaqus.
0 Kudos
mecej4
Honored Contributor III
2,135 Views
With regard to the specific question "... would the code which I have posted work?": I cannot agree with your statement that "it is entirely related to Fortran programming". A subroutine call can be entirely correct as to syntax, yet be totally wrong with respect to the arguments passed.

It is impossible to answer this question without knowing the Abaqus interface and, therefore, the question is best answered by Abaqus customer support or in an Abaqus user forum.
0 Kudos
Greg_T_
Valued Contributor I
2,135 Views
Hello,

When debugging and testing an Abaqus user-subroutine I have found it useful to write values from the user-subroutineto the Abaqus Message (*.msg) file. The .msg file unit number is unit 7. You can refer to the Abaqus Analysis User's Manual, section 3.7.1 "Fortran unit numbers used by Abaqus".

I would think that looping through the COORDS array to extract values shoudl work.Extracting single values from thePROPS array looks okay to me. Have you triedcompiling or running the UEL routine with Abaqus yet?

One possibleconcern is that MCRD is passed in to the UEL routine for the COORDS array size, but the local arrays v1 through v9 have a fixed size of 3 (for the 3 x,y,z node DOF I assume). Perhaps a check on MCRD being 3 would avoid a crash if MCRD > 3 for some reason(you can also write errors to the Abaqus files), or perhaps consider if allocatable arrays would be useful by using the given MCRD for the local array size.

Regards,
Greg
0 Kudos
guruduttc
Beginner
2,135 Views
Hello Greg,

You totally seem to understand my problem here.
I have executed the above code in Abaqus.There is no problem with the compilation.But the final result which I get looks fishy. The above code is written to extract the stiffness matrix of a user elemnt(if you are familiar with what I am speaking!).However ,the code seems to work in Abaqus with or without the following block:
do i=1,MCRD
v1(i)=COORDS(i,1)
v2(i)=COORDS(i,2)
v3(i)=COORDS(i,3)
v4(i)=COORDS(i,4)
v5(i)=COORDS(i,5)
v6(i)=COORDS(i,6)
v7(i)=COORDS(i,7)
v8(i)=COORDS(i,8)
v9(i)=COORDS(i,9)
enddo
E=PROPS(1)
ni=PROPS(2)
H=PROPS(3)
e31=PROPS(4)
d33=PROPS(5)


The final values of all the terms in my stiffness matrix are zeroes with or without the above block.(As you can see in the call Kij statement,the arguments KM11,kM12,kM13..........etc etc are the terms in my stiffness matrix which are later assigned to AMATRX array which is then passed back to the UEL subroutiine so that Abaqus can use those values)

My concern is that somehow,the values assigned to v1,v2,v3,v4,v5,v6,v7,v8,v9 arrays and E,ni,H,e31,d33 quantities are not being passed to the arguments in the Kij subroutine through the call Kij statement. I used an interface to pass the values,but then realized it is not really necessary as I learnt that if a subroutine compiles perfectly, it would not make a diference whether we use or dont use an interface to pass values.

Perhaps I must now try the allocatable arrays as you suggested and also check for MCRD being equal to 3.

Thanks for your suggestion...Please let me know if you think of anything more I could do...

Cheers
Gurudutt

0 Kudos
mecej4
Honored Contributor III
2,135 Views
I think that this thread has reached a point where it should be moved to an Abaqus forum. However, I seem to have induced you reach an incorrect understanding of the role that interfaces play, because you said:

.."but then realized it is not really necessary as I learnt that if a subroutine compiles perfectly, it would not make a diference whether we use or dont use an interface to pass values"

That is simply not correct. If you add ", links and works" between "compiles" and "perfectly", the statement becomes correct.

Along the same lines, your statement that "I used an interface to pass the values" is also incorrect.

An interface provides information to the compiler to enable the latter to produce correct code. Therefore, and interface cannot do things such as passing values or making the code run faster. Having an incorrect interface can be worse than having no interface.

The same information can be provided in other ways (by using correct type, shape and size declarations of variables, passing the correct number of arguments in the proper order).

It is when the subroutine call or function reference is incompatible with the interface that the redundancy that is provided by an interface becomes beneficial. The incompatibility may be caused by simple programming errors, or by a misunderstanding of the calling conventions of a library routine. Regardless, the compiler will tell you that there is an incompatibility and may give you some particulars of the incompatibility. It is still up to you to remove the incompatibility.
0 Kudos
Greg_T_
Valued Contributor I
2,136 Views
Hello,

I would recommend testing taking advantage of Intel Fortran (IVF)and Visual Studio (VS)if possible, outside of the Abaqus analysis, for inital testing and debugging. I recommend writing a main program that can run the user subroutine so that testing can be done entirely within VS, or by IVF from the command line. Perhaps you could write the allvalues passed into the user subroutine from Abaqus to the *.msg file for just one element (a single element mesh), which would give you the values the main testing program would duplicate in the stand-alone test. Then you can run the single element with the user subroutine by itself entirely within IVF and VS to see if it is working as expected and take advantage of the debugging tools if that would help. I suppose this approach is within the category of general Fortran debugging and testing and may be obvious. But perhaps this way would allow you to check the problem of the passed values and local arrays. This method has helped me in the past. Then once the stand-alonetest is working, return to Abaqus and check that the same single element test works there too. Hopefully writing all the values to the *.msg file and comparing to the debugging output from the testing in VS, something won't match andwill help reveal the cause of the array and value problem.

If a problem remains, then the single element mesh will also be a good example to submit to the Abaqus technical support for advice.

On a side note, I was suprised to see my previous post in a different color. I don't think I selected another option that would cause that, and it hasn't happened for other posts. Is there an editing option I should change?

Regards,
Greg
0 Kudos
mecej4
Honored Contributor III
2,135 Views
On a side note, I was suprised to see my previous post in a different color. I don't think I selected another option that would cause that, and it hasn't happened for other posts. Is there an editing option I should change?

No, rejoice! The color, which may be shown or hidden depending on your browser settings, is a signal that the originator of the thread flagged one of your responses as "best answer".
0 Kudos
guruduttc
Beginner
2,135 Views
Thanks a lot for the suggestion.I created a program called TestUelSubroutine .I assigned values to the COORDS and PROPS array. I then passed these values to the UEL subroutine.


++++++++++++++++++++++++++++++++++++++++++++++++++++
program TestUelSubroutine


implicit none

real*8::PROPS(5),COORDS(3,9),AMATRX(72,72)


DATA PROPS(1),PROPS(2),PROPS(3),PROPS(4),PROPS(5)/1.0,2.0,3.0,4.0,5.0/
DATA COORDS(1,1),COORDS(1,2),COORDS(1,3)/6.0,7.0,8.0/
DATA COORDS(1,2),COORDS(2,2),COORDS(2,3)/9.0,10.0,11.0/
DATA COORDS(1,3),COORDS(2,3),COORDS(3,3)/12.0,13.0,14.0/
DATA COORDS (1,4),COORDS(2,4),COORDS(3,4)/ 15.0,16.0,17.0/
DATA COORDS (1,5),COORDS(2,5),COORDS(3,5)/18.0,19.0,20.0/
DATA COORDS (1,6),COORDS(2,6),COORDS(3,6)/21.0,22.0,23.0/
DATA COORDS (1,7),COORDS(2,7),COORDS(3,7)/24.0,25.0,26.0/
DATA COORDS (1,8),COORDS(2,8),COORDS(3,8)/27.0,28.0,29.0/
DATA COORDS (1,9),COORDS(2,9),COORDS(3,9)/30.0,31.0,32.0/

call UEL(AMATRX,PROPS,COORDS)
PRINT *, "AMATRX(1,1) = ", AMATRX(1,1)
PRINT *, "AMATRX(1,2) = ", AMATRX(1,2)

end program TestUelSubroutine
****************************************************************
subroutine UEL(AMATRX,PROPS,COORDS)


implicit none

real*8:: AMATRX(72,72),PROPS(5),COORDS(3,9)
.....................................
..................................... lines defining the subroutine UEL......

++++++++++++++++++++++++++++++++++++++++++++++++++



If I debug the above program ,I get the following message


console8.exe': Loaded 'C:\Dokumente und Einstellungen\nilgur4x\Eigene Dateien\Visual Studio 2008\Projects\Console8\Console8\Debug\console8.exe', Symbols loaded.
'console8.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll'
'console8.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll'
'console8.exe': Loaded 'C:\WINDOWS\system32\imagehlp.dll'
'console8.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll'
The program '[3132] console8.exe: Native' has exited with code 0 (0x
0).


My question is as follows......

If I try to run the executable file,the window just appears and then disappears within a fraction of a second. I see that there is an output but the window just doesnt stay long enough for me to note the values of the output...why does this happen?I dont see any error in what I have done....

This may be a very simple issue,but I dont seem to get it.....I am familiar with some Fortran 77 programming..May be I am mixing up F77 and F90 styles.


0 Kudos
mecej4
Honored Contributor III
2,135 Views
Exiting with status code 0 is the normal behavior of a console application. To interrupt the program before it quits, you may put a PAUSE statement before the END line of the main program, or use controls provided to you by the IDE. Or, you can run the .EXE in a command window.
0 Kudos
Reply