- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
I am new to fortran coding so forgive me if my question is trivial. I am coding some Fortran subroutines that will help me solving and Abaqus finite element simulation. The subroutine works in this way: it takes data from Abaqus makes some calculation and then update some variables. I have some problems with a matrix (OLDECE2N) that was built to save a variable (ECE2N) from the previous time increment of the simulation. E.g. if I am in step 1 I save OLDECE2N(I,J)=ECE2N(I,J) so that when I am in step 2 I can read ECE2 at step 1 through OLDECE2.
Here is how I define OLDECE2N (NELX=13 and NELY=5, previously defined):
DIMENSION OLDECE2N(NELX,NELY)
Since at first step there is no ECE2N value I set OLDECE2N to zero in this way:
IF(STEP.EQ.1) THEN
DO II=1,NELX
DO JJ=1,NELY
OLDECE2N(II,JJ)=0
END DO
END DO
END IF
So finally at the end of my calculations i save ECE2N values to OLDECE2N:
DO II=1,NELX
DO JJ=1,NELY
OLDECE2N(II,JJ)=ECE2N(II,JJ)
END DO
END DO
Unfortunately it doesn't work as it should. In fact OLDECE2N does not contain all the right data (see the attachment .log). especially first value OLDECE2N(1,1) = 5.0519-316 I don't know where it comes from. I was able to solve the problem by changing DIMENSION and by adding DATA:
DIMENSION OLDECE2N(13,5)
DATA OLDECE2N/0*0/
but I don't want to write the values 13 and 5 by myself everytime. I want fortran to do that for me. Any idea?
Thank you in advance
Federico
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you are content with fixed values for NELX and NELY, you can declare them as integer parameters.
If not, you could create a module with OLDECE2N an allocatable array in it. USE that module wherever you need to use OLDECE2N. As long as the module does not go out of scope, variables in the module will retain their values.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the declaration of OLDECN, you need to specify the SAVE attribute. Otherwise, OLDECN is a local variable that becomes undefined when you exit the subroutine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mecej4 can you please provide me an example?
Thank you in advance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something like
DIMENSION, SAVE :: OLDECE2N(NELX,NELY)
Or as a separate statement after the DIMENSION statement
SAVE :: OLDECE2N
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your help. I've tried both but didn't work:
DIMENSION OLDECE2N(NELX,NELY)
SAVE :: OLDECE2N
produced: CT3DV2.for(141):
CT3DV2.for(141): error #6754: An automatic object must not appear in a SAVE statement or be declared with the SAVE attribute. [OLDECE2N]
8 FSMULTIN(NELX,NELY),VERVECT(NELY),OLDECE2N(NELX,NELY)
------------------------------------------------------------------^
while:
DIMENSION, SAVE :: OLDECE2N(NELX,NELY)
produces:
CT3DV2.for(142): error #5277: Syntax error, found ',' following statement keyword
DIMENSION , SAVE :: OLDECE2N(NELX,NELY)
------------------^
CT3DV2.for(142): error #5082: Syntax error, found '::' when expecting one of: ( [
DIMENSION , SAVE :: OLDECE2N(NELX,NELY)
-----------------------^
CT3DV2.for(142): error #5082: Syntax error, found END-OF-STATEMENT when expecting one of: ) , :
DIMENSION , SAVE :: OLDECE2N(NELX,NELY)
---------------------------------------------^
Do you think that having defined NELX and NELY in another subroutine and called via \COMMON might be the problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If OLDECE2N is passed into the subroutine it should not have SAVE. The SAVe would be for variables that are only defined (created) in the subroutine so that on the next entry to the subroutine they still have the values from the end of the last visit.
One more point you do not need a loop for OLDECE2N(II,JJ)=0 you can just write OLDECE2N=0 which will set all elements of the array. You can also have OLDECE2N=ECE2N which will assign all elements the arrays being the same size and shape.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Federico, you should post the entire code (use the {...}_code button to do so, or post as attachment). Otherwise, you will continue to see suggestions that may not work if you use them literally. For example, take the suggestion in #4. You have not told us what the type of OLDECE2N is or shown us the declaration of that variable, nor have you told us whether the variable is a dummy argument.
If it is a REAL local array, for example, the declaration could be
REAL , SAVE :: OLDECE2N(NELX,NELY)
However if OLDECE2N is a dummy argument, it would be incorrect to attempt to give it the SAVE attribute. Furthermore, in this case the array may have acquired unexpected values because the memory that it formerly occupied may be overwritten elsewhere. As you can see, there are many possibilities.
That is why we need to see the whole code. It may be acceptable for someone new to Fortran to ask for help with running code that is known to be complete and correct, but fixing modified code that is not shown? Not likely to work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Federico,
Have you also written a "main.f90" program that can run the user subroutine separately from Abaqus? When I am using a user subroutine in Abaqus I have found it is very helpful to first write a main program to run and test the user subroutine: pass in the needed arguments from main to the subroutine, and output the returned values. I think a main program to run the subroutine would help in this case too, to test and check on the issue with the OLDECE2N array. And you would have a complete program and subroutine that you could post here.
Regards,
Greg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is the model, I've cleaned all the unimportant passages. Thank you I really appreciate your help.
Fede
Line 14 > I define NELX and NELY
Line 32 > I define OLDECE2N
Line 45 > I set to zero OLDECE2N at the first time increment
Line 67 > I order abaqus values inside my variable ECE2N
Line 77 > I write OLDECE2N and ECE2N
Line 91 > I update OLDECE2N value to ECE2N after I had calculated ECE2N derivative
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C SUBROUTINE MPC(UE,A,JDOF,MDOF,N,JTYPE,X,U,UINIT,MAXDOF,LMPC, 1 KSTEP,KINC,TIME,NT,NF,TEMP,FIELD,TRAN,LTRAN) C INCLUDE 'ABA_PARAM.INC' C DIMENSION UE(MDOF), A(MDOF,MDOF,N), JDOF(MDOF,N), X(6,N), 1 U(MAXDOF,N), UINIT(MAXDOF,N), TIME(2), TEMP(NT,N), 2 FIELD(NF,NT,N),LTRAN(N),TRAN(3,3,N) COMMON /TRASPORTO/ APICE, CTINT, NELAPERTI, NELX, NELY DATA APICE/6.30/ C NELX=13 NELY=5 C (...)HERE I DO SOME STUFF BUT NOT RELATED TO THE FOLLOWING SUBROUTINES RETURN END C SUBROUTINE URDFIL(LSTOP, LOVRWRT,KSTEP,KINC,DTIME,TIME) INCLUDE 'ABA_PARAM.INC' DIMENSION ARRAY(513),JRRAY(NPRECD,513),TIME(2),VARMIS(NELX*NELY), 1 VARPRE(NELX*NELY),VARCE(NELX*NELY),SMISES(80,4),SPRESS(80,4), 2 ECE2(80,4),OLDECE2(80,4),CEP(80,4),OMEGAP(80,4),OMEGATOT(80,4), 3 INO(80),OLDOMEGATOT(80,4),IK(80,2),COUNTER(2),FSMULTI(80,4), 4 CTINT(1),OLDLLD(1),Vss(1),CStar(1),OMEGADISP(80-NELAPERTI,2), 5 SMISESN(NELX,NELY),SPRESSN(NELX,NELY),ECE2N(NELX,NELY), 6 CEPN(NELX,NELY),OMEGAPN(NELX,NELY), 7 OMEGATOTN(NELX,NELY),OLDOMEGATOTN(NELX,NELY), 8 FSMULTIN(NELX,NELY),VERVECT(NELY),OLDECE2N(NELX,NELY) EQUIVALENCE (ARRAY(1),JRRAY(1,1)) COMMON /TRASPORTO/ APICE, CTINT, NELAPERTI, NELX, NELY C C DATI Provino 1 con cricca lunga C DATA OLDTIME/0.D0/,OLDECE2/320*0/,OMEGAP/320*0/,OLDOMEGATOT/320*0/ 1 ,OMEGATOT/320*0/,NELAPERTI/0/,COUNTER/0.D0,1/,FSMULTI/320*0/, 2 INO/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, 3 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 4 41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60, 5 61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80/, 6 OLDLLD/0.D0/,Vss/0.D0/ IF(KINC.EQ.1) THEN DO II=1,NELX DO JJ=1,NELY OLDOMEGATOTN(II,JJ)=0 OLDECE2N(II,JJ)=0 END DO END DO END IF C C inizializzo per ogni incremento C JEL=0 JPNT=0 JSPNT=0 INDICE=0 APICEINIZIALE=6.30 NEL=13 CRICCA=13.1 C C (...) HERE I CALL VARMIS VARPRE AND VARCE FROM ABAQUS RESULT FILE AND SAVE THEM TO ECE2N SPRESSN AND C KK=1 DO JJ=1,NELY DO II=1,NELX SMISESN(II,JJ)=VARMIS(KK) SPRESSN(II,JJ)=VARPRE(KK) ECE2N(II,JJ)=VARCE(KK) KK=KK+1 END DO END DO CONTINUE C WRITE(*,*)'KINC ',KINC,' TIME ',TIME(1)-OLDTIME DO II=1,NELX WRITE(*,129)' ECE2N ',ECE2N(II,1),' ',ECE2N(II,2),' ', 1 ECE2N(II,3),' ',ECE2N(II,4),' ',ECE2N(II,5) END DO DO II=1,NELX WRITE(*,129)' OLDECE2N ',OLDECE2N(II,1),' ',OLDECE2N(II,2),' ', 1 OLDECE2N(II,3),' ',OLDECE2N(II,4),' ',OLDECE2N(II,5) END DO C------------------OMEGA CALCULATION IN 3D SIMULATIONS START------------------ DO II=1,NELX DO JJ=1,NELY C EQUIVALENT CREEP STRAIN RATE CALC CEPN(II,JJ)=(ECE2N(II,JJ)-OLDECE2N(II,JJ))/(TIME(1)-OLDTIME) OLDECE2N(II,JJ)=ECE2N(II,JJ) END DO END DO 129 FORMAT(A,ES15.4,A,ES15.4,A,ES15.4,A,ES15.4,A,ES15.4) RETURN END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You really need to include the file 'ABA_PARAM.INC'
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now that you have posted the code, I see the problem. Note that you should have posted the code in the include file, as well. In the following, I assume that the file contains "implicit real*8(a-h,o-z)" and "integer, parameter (nprecd=2)".
The array declaration contains OLDECE2N(NELX,NELY). Since NELX and NELY are variables in COMMON, with values that are not known at compile time, the size of OLDECE2N is not known at compile time and the array cannot be given the SAVE attribute.
You will have to think of another way of handling the problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mecej4 you were right with the ABA_PARAM.INC assumption. I case I could define NELX and NELY in URDFIL subroutine avoiding COMMON block, how should I define them in order to be already known at compile time?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you are content with fixed values for NELX and NELY, you can declare them as integer parameters.
If not, you could create a module with OLDECE2N an allocatable array in it. USE that module wherever you need to use OLDECE2N. As long as the module does not go out of scope, variables in the module will retain their values.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all for your help, I solved by following mecej4 suggestion and by adding NELTOT.
SUBROUTINE URDFIL(LSTOP, LOVRWRT,KSTEP,KINC,DTIME,TIME) INCLUDE 'ABA_PARAM.INC' DIMENSION ARRAY(513),JRRAY(NPRECD,513),TIME(2), 1 SMISES(80,4),SPRESS(80,4), 2 ECE2(80,4),OLDECE2(80,4),CEP(80,4),OMEGAP(80,4),OMEGATOT(80,4), 3 INO(80),OLDOMEGATOT(80,4),IK(80,2),COUNTER(2),FSMULTI(80,4), 4 CTINT(1),OLDLLD(1),Vss(1),CStar(1),OMEGADISP(80-NELAPERTI,2) EQUIVALENCE (ARRAY(1),JRRAY(1,1)) COMMON /TRASPORTO/ APICE, CTINT, NELAPERTI C DATI Provino 1 con cricca lunga INTEGER*4 NELX, NELY, NELTOT PARAMETER (NELX=13,NELY=5,NELTOT=65) DIMENSION VARMIS(NELTOT),VARPRE(NELTOT),VARCE(NELTOT), 1 SMISESN(NELX,NELY),SPRESSN(NELX,NELY),ECE2N(NELX,NELY), 6 CEPN(NELX,NELY),OMEGAPN(NELX,NELY), 7 OMEGATOTN(NELX,NELY),OLDOMEGATOTN(NELX,NELY), 8 FSMULTIN(NELX,NELY),VERVECT(NELY),OLDECE2N(NELX,NELY) DATA OLDECE2N/NELTOT*0/
I seriously need to better understand Fortran coding though. Do you have some free guide to suggest me?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Have a look at http://www.fortran.com/the-fortran-company-homepage/fortran-tutorials/

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page