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

Problem with Variables definition

Federico_B_
Beginner
2,939 Views

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

 

 

0 Kudos
1 Solution
mecej4
Honored Contributor III
2,939 Views

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.

View solution in original post

0 Kudos
14 Replies
mecej4
Honored Contributor III
2,939 Views

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.

0 Kudos
Federico_B_
Beginner
2,939 Views

mecej4 can you please provide me an example?
Thank you in advance

0 Kudos
DavidWhite
Valued Contributor II
2,939 Views

Something like

DIMENSION, SAVE :: OLDECE2N(NELX,NELY)

Or as a separate statement after the DIMENSION statement

SAVE :: OLDECE2N

0 Kudos
Federico_B_
Beginner
2,939 Views

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?

 

0 Kudos
andrew_4619
Honored Contributor III
2,939 Views

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.

 

 

0 Kudos
mecej4
Honored Contributor III
2,939 Views

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.

0 Kudos
Greg_T_
Valued Contributor I
2,939 Views

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

0 Kudos
Federico_B_
Beginner
2,939 Views

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

 

0 Kudos
andrew_4619
Honored Contributor III
2,939 Views

You really need to include the file  'ABA_PARAM.INC'

0 Kudos
mecej4
Honored Contributor III
2,939 Views

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.

0 Kudos
Federico_B_
Beginner
2,939 Views

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?

0 Kudos
mecej4
Honored Contributor III
2,940 Views

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.

0 Kudos
Federico_B_
Beginner
2,939 Views

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?

0 Kudos
Steven_L_Intel1
Employee
2,939 Views

Have a look at http://www.fortran.com/the-fortran-company-homepage/fortran-tutorials/

 

0 Kudos
Reply