- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear All
I am trying to write a Fortran subroutine (which is consisted of several subroutines) for Abaqus. In a part of it:
I am passing an existing element list (which is a 2d array (n,2) ) to another subroutine and try to extend it (it will read files but I tried to do simple case first and try to extend a 3x2 array to 5x2array):
INTEGER, DIMENSION(:,:), ALLOCATABLE :: MYELLIST
ALLOCATE(MYELLIST(3,2))
...
CALL TEST_SUBROUTINE(MYELLIST,KN)
KN is the current size so that we can dimension the MYELLIST array on the 2nd subroutine:
SUBROUTINE TEST_SUBROUTINE(MYELLIST,KN)
...
INTEGER, DIMENSION(:,:), ALLOCATABLE :: TEMPLIST
DIMENSION MYELLIST(KA,2)
...
I tried to define a TEMPLIST with the proper size (extending KA with +KB = 5 here in simple case) and first copy the MYELLIST into it and after that add additional values:
ALLOCATE(TEMPLIST(KA+KB,2))
DO i=1,KA
TEMPLIST(i,1) = MYELLIST(i,1)
TEMPLIST(i,2) = MYELLIST(i,2)
ENDDO
...
The problem is when I am trying to replace the MYELLIST with TEMPLIST an error will rise:
deallocate(MYELLIST)
call move_alloc(TEMPLIST, MYELLIST)
or even:
deallocate(MYELLIST)
allocate(MYELLIST(5,2))
MYELLIST = TEMPLIST
It seems as soon as I deallocate the MYELLIST an error will terminate the job.
It think Abaqus subroutines are limited to Fortran 77 or 90 fixed form.
And I am really a beginner and have very limited knowledge in programming so please forgive me if my question is inconvenient.
Many Thanks in advance
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your code shows an argument KN but a declaration that uses KA. As you do not show the entire routine, this is simply guessing, but could it be that KA is not defined and should instead be KN? You can guard against this sort of things by using the statement "IMPLICIT NONE". It forces you to explicitly declare all variables in your code. That way many typos are easily corrected.
If this is not the case, then it would help if you posted complete code that reproduces the problem - the smaller the better, but sometimes that is quite difficult.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Arjen-Markus
Unfortunately that is not the problem, I tested the rest of the program and it will run with no errors, but as soon as I try to deallocate the array it will terminate.
I tried to simplified the code, I renamed the variables and contain only the problem part (everything works fine until the deallocation line added):
SUBROUTINE UVARM(UVAR,DIRECT,T,TIME,DTIME,CMNAME,ORNAME,
C
1 NUVARM,NOEL,NPT,LAYER,KSPT,KSTEP,KINC,NDI,NSHR,COORD,
2 JMAC,JMATYP,MATLAYO,LACCFLA)
C
INCLUDE 'ABA_PARAM.INC'
C
LOGICAL, SAVE :: FIRSTRUN = .TRUE.
CHARACTER*80 CMNAME,ORNAME
CHARACTER*3 FLGRAY(15)
INTEGER KA
INTEGER, DIMENSION(:,:), ALLOCATABLE :: MYELLIST
DIMENSION UVAR(NUVARM),DIRECT(3,3),T(3,3),TIME(2)
DIMENSION ARRAY(15),JARRAY(15),JMAC(*),JMATYP(*),COORD(*)
C
C test a simple 3x2 array
MYELLIST(1,1) = 1
MYELLIST(2,1) = 2
MYELLIST(3,1) = 3
MYELLIST(1,2) = 11
MYELLIST(2,2) = 22
MYELLIST(3,2) = 33
KA = 3
IF (FIRSTRUN) THEN
ALLOCATE(MYELLIST(3,2))
CALL TEST_SUB(MYELLIST,KA)
C if this works it should print new values
WRITE(6,*) MYELLIST
WRITE(6,*) MYELLIST
FIRSTRUN = .FALSE.
ENDIF
C
RETURN
END
C
C----------------------------------------------------------------------
C
SUBROUTINE TEST_SUB(MYELLIST,KA)
INTEGER KA, KB, i
INTEGER, DIMENSION(:,:), ALLOCATABLE :: TEMPLIST
DIMENSION MYELLIST(KA,2)
C
C at first i just change thee values with same size and its ok
C i got the changed array in the first subroutine
GRAINID = GRAINID + 1
MYELLIST(1,1) = 11
MYELLIST(2,1) = 22
MYELLIST(3,1) = 33
MYELLIST(1,2) = 111
MYELLIST(2,2) = 222
MYELLIST(3,2) = 333
C
KB = 2
ALLOCATE(TEMPLIST(KB+NPLUS,2))
DO i=1,KA
TEMPLIST(i,1) = MYELLIST(i,1)
TEMPLIST(i,2) = MYELLIST(i,2)
ENDDO
TEMPLIST(KA+1,1) = 4
TEMPLIST(KA+1,2) = 44
TEMPLIST(KA+2,1) = 5
TEMPLIST(KA+2,2) = 55
C I can read the changed KA (3->5) on the other subroutine
C but i didnt find a way to replace MYELLIST with TEMPLIST
KA = KA+KB
C
deallocate(MYELLIST)
allocate(MYELLIST(5,2))
MYELLIST = TEMPLIST
C Or this way:
C deallocate(MYELLIST)
C call move_alloc(TEMPLIST, MYELLIST)
C
RETURN
END
And I believe it is IMPLICIT NONE, because it is will give compilation error if any variable is not defined properly.
Is there any other way that we can extend an array?
for example we have an existing array then we read several files in a loop and each time add some elements at the end of array?
Thank you
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hm, what is the exact error message you get?
An alternative would be to rely on automatic reallocation, but that merely hides the deallocation that will take place:
real, allocatable :: a, b
allocate(b(100), a(50))
b = 1.0
a = b ! Automatical reallocation happens because the left-hand side is allocatable
You may get errors regarding deallocation if the array is not actually allocated or if somehow the memory is corrupted. The error messages that are printed on the console/terminal window should tell you what is going wrong. (However, in some environments this is hidden, unfortunately.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your reply
I got: Problem during compilation, but since it is in Abaqus software I can't find out what is the exact problem.
Everything is okay but as soon as I add:
deallocate(MYELLIST)
call move_alloc(TEMPLIST, MYELLIST)
It will lead to the mentioned error.
------
In the second subroutine, If I just declare it this way:
INTEGER, DIMENSION(:,:), ALLOCATABLE :: MYELLIST
As soon job get to this part of code it will terminate.
So the only way it will work is to define the dimension:
DIMENSION MYELLIST(KA,2)
And I tried your suggestion, unfortunately it wont change the size of array and data written to it will be false
Thanks again
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please try with an explicit interface for your TEST_SUB and see if that helps. I don't know how the build toolchain config with ABAQUS works. It's possible with TEST_SUB as external procedure, its interface is not visible to your UVARM method (it usually requires a compiler option such as gen-interfaces with Intel compiler). Hence this suggestion. Please see below as an option - note it's untested, so excuse any typos.
SUBROUTINE UVARM(UVAR,DIRECT,T,TIME,DTIME,CMNAME,ORNAME,
C
1 NUVARM,NOEL,NPT,LAYER,KSPT,KSTEP,KINC,NDI,NSHR,COORD,
2 JMAC,JMATYP,MATLAYO,LACCFLA)
C
INCLUDE 'ABA_PARAM.INC'
C
LOGICAL, SAVE :: FIRSTRUN = .TRUE.
CHARACTER*80 CMNAME,ORNAME
CHARACTER*3 FLGRAY(15)
INTEGER KA
INTEGER, DIMENSION(:,:), ALLOCATABLE :: MYELLIST
DIMENSION UVAR(NUVARM),DIRECT(3,3),T(3,3),TIME(2)
DIMENSION ARRAY(15),JARRAY(15),JMAC(*),JMATYP(*),COORD(*)
C Add explicit interface for TEST_SUB
INTERFACE
SUBROUTINE TEST_SUB(MYELLIST,KA)
C Specify Argument list and make intent clear
INTEGER, ALLOCATABLE, INTENT(INOUT) :: MYELLIST(:,:)
INTEGER, INTENT(IN) :: KA
END SUBROUTINE
END INTERFACE
C
C test a simple 3x2 array
MYELLIST(1,1) = 1
MYELLIST(2,1) = 2
MYELLIST(3,1) = 3
MYELLIST(1,2) = 11
MYELLIST(2,2) = 22
MYELLIST(3,2) = 33
KA = 3
IF (FIRSTRUN) THEN
ALLOCATE(MYELLIST(3,2))
CALL TEST_SUB(MYELLIST,KA)
C if this works it should print new values
WRITE(6,*) MYELLIST
WRITE(6,*) MYELLIST
FIRSTRUN = .FALSE.
ENDIF
C
RETURN
END
C
C----------------------------------------------------------------------
C
SUBROUTINE TEST_SUB(MYELLIST,KA)
C Specify Argument list and make intent clear
INTEGER, ALLOCATABLE, INTENT(INOUT) :: MYELLIST(:,:)
INTEGER, INTENT(IN) :: KA
C Local variables
INTEGER KB, i
INTEGER, ALLOCATABLE :: TEMPLIST(:,:)
C
C at first i just change thee values with same size and its ok
C i got the changed array in the first subroutine
GRAINID = GRAINID + 1
MYELLIST(1,1) = 11
MYELLIST(2,1) = 22
MYELLIST(3,1) = 33
MYELLIST(1,2) = 111
MYELLIST(2,2) = 222
MYELLIST(3,2) = 333
C
KB = 2
ALLOCATE(TEMPLIST(KB+NPLUS,2))
DO i=1,KA
TEMPLIST(i,1) = MYELLIST(i,1)
TEMPLIST(i,2) = MYELLIST(i,2)
ENDDO
TEMPLIST(KA+1,1) = 4
TEMPLIST(KA+1,2) = 44
TEMPLIST(KA+2,1) = 5
TEMPLIST(KA+2,2) = 55
C I can read the changed KA (3->5) on the other subroutine
C but i didnt find a way to replace MYELLIST with TEMPLIST
KA = KA+KB
C
deallocate(MYELLIST)
allocate(MYELLIST(5,2))
MYELLIST = TEMPLIST
C Or this way:
C deallocate(MYELLIST)
C call move_alloc(TEMPLIST, MYELLIST)
C
RETURN
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FWIW
Your upper level subroutine UVARM is writing to individual cells of the unallocated MYELLIST array, then performing an ALLOCATE on this array. As to why this did not error out, I cannot say. Also, as to why you observe the initial values (written to the unallocated and prior to allocation) is more perplexing.
Have you run this with full runtime diagnostics?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
deallocate(MYELLIST)
call move_alloc(TEMPLIST, MYELLIST)
The deallocate above is not needed. The move_alloc makes mylist point at templist data and will "deallocate" templist automatucally so only Myellist then exists. I have not tested but in all my usage cases of move_alloc both arrays are allocated at the time of the move_alloc. It would seem pointless for this not to be so and I would imagine it my be a requirement.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is not a requirement that the TO array be allocated, but if it is, it is automatically deallocated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan
Thank you for your reply. It did not work at first try but I will put more effort on it in the next days.
@Steve_Lionel , @andrew_4619
Thanks you for your replies.
I tried without deallocation and still got compilation error.
All the Help documents in Abaqus have subroutines written in F77, and I think by default it forces the code to compile with F77 compiler. The error is maybe because MOVE_ALLOC is supported in Fortran 2003 and later. I believe it is possible to extend compiler options in Abaqus to recognize and compile newer versions.
I have no knowledge so excuse me if my words don't make any sense, but another thing that may caused the error is parallel running of subroutines in several nodes.
But I will try more in the next days.
Thank you very much for your replies.
Regards
Emma
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
what compiler (specific version) are you using?
what is the compiler error? exact error message? There is quite a bit of guesswork going on with many of the answers people are making because the basics of the problem lack definition. A compiler error is normally a very simple matter to diagnose and fix, Fortran has well defined rules.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
C:\test>ifort /c uvarm.for
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1 Build 20201112_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
uvarm.for(6): error #5102: Cannot open include file 'ABA_PARAM.INC'
INCLUDE 'ABA_PARAM.INC'
--------------^
uvarm.for(67): error #6724: An allocate/deallocate object must have the ALLOCATABLE or POINTER attribute. [MYELLIST]
deallocate(MYELLIST)
-----------------^
uvarm.for(68): error #6724: An allocate/deallocate object must have the ALLOCATABLE or POINTER attribute. [MYELLIST]
allocate(MYELLIST(5,2))
---------------^
compilation aborted for uvarm.for (code 1)
Well the first error is that I don't have the include file but the other two errors are quite clear.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Re: "All the Help documents in Abaqus have subroutines written in F77, and I think by default it forces the code to compile with F77 compiler."
This is not the case. F77 code is also F2018 code (with rare exceptions), and there is no "F77 compiler" that you have.
Please show a small but complete example demonstrating the error and give us the full text of the error message (along with the line it is complaining about.)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page