Fortran: Clearing defined array when leaving subroutine
I am doing a sensitivity analysis and thus need to run my program many times with different parameters. I do have a main program which calls the subroutine that calculates the values I need. Thus I need to call the subroutine many times.
The subroutine has some arrays define开发者_StackOverflowd as:
real, dimension(1000) :: array_1, array_2
After leaving the array the program does not free the array, thus for two calls of the function I need to write:
real, dimension(2000) :: array_1, array_2
Is there an easy solution for this ? Thank you
Let me restate your problem, just to make sure I understand it correctly; please correct me if I'm wrong.
- You have a subroutine that calculates 1000 values in two separate arrays: array_1 and array_2.
- From your main program you would like to call this subroutine many times, each time generating a unique sets of 1000 values.
Let's say you want to call your subroutine N times, do you want to compare the N sets of numbers out side of the subroutine, ie in your main program, or do you want to do the comparison inside the subroutine?
Either way, I declare the arrays like so:
real, dimension(N,1000) :: array_1, array_2
If you would like to do the comparison outside the subroutine, you will make the above declaration in the main program. Then you will call the subroutine N times, and after each i'th time copy the values into the main's array_1(i,*) and array_2(i,*). In this, the subroutine will only have the arrays defined like so:
real, dimension(1000) :: array_1, array_2
Each time the subroutine is called, it will reuse these arrays, overwriting the previous values. This should be OK if you recorded the previous values in the main's arrays.
If you are doing this in f90, you can dynamically allocate array_1 and array_2 and let N be variable length. Alternatively, you can allocate the arrays initially with enough space to store all possible calls to the subroutine. Lets say you are not going to run more than 100 calls to the subroutine:
real array_1(100,1000), array_2(100,1000)
I'm sorry if this is not what you are looking for, but please clarify if I miss understood your question.
If you have many arrays with essentially the same data, naming them array, array_1, array_2, etc. will soon become awkward, as you have realized. Two other possible designs are: 1) use one array and process the data in a loop. After one group of data is processed, read in the next group and overwrite the previous data in the same array. 2) Use a two-dimensional array as suggested by @Yann, with the second dimension being the number of datasets / different sets of parameters values.
If the arrays of each dataset have different lengths, for solution 1 you could declare the array "allocatable" and allocate it to the correct length at the start of each iteration, then deallocate at the end of each iteration. For 2 it would probably be easiest (but not most memory efficient) to make the length the maximum length and have an auxiliary array specifying the used length.
P.S. Are these arrays local to the subroutine? Then if you are passing the length to the subroutine as an argument, e.g., "len", you can declare the arrays as:
integer, intent (in) :: len
real, dimension(len) :: array_1, array_2
and the arrays will be recreated when the subroutine is re-invoked with the particular length "len". Inside a procedure (subroutine or function), and if the length is passed as an argument, you can get a variable length array very simply. You can even obtain the length using the size function applied to an array argument! In the main program, or it the length is not known as a constant or argument to a procedure, then you can defer the size of the array by giving it the "allocatable" attribute in the declaration and dynamically allocate the array with the "allocate" statement.
精彩评论