2

The project that I am working in, requires that a considerable amount of arrays should be passed through a bunch of subroutines and functions, so I opt for a module.

These arrays are all allocatable, they don't cause much trouble, except when I have to explicit which of these array a subroutine should use. The way I manage the code to run, it's completly overkill.

The way it's working:

Program Principal
 Use Info
 open(unit=1,file="dadose6h.dat")
 call get_data
 call sortsupply
 call sortcost
 call ratecapacity
end Program

Module Info
 integer i,j
 integer, dimension (:), allocatable :: supply
 integer, dimension (:), allocatable :: cost
 integer, dimension (:,:), allocatable :: capacity
 integer, dimension (:,:), allocatable :: demand
End module info


subroutine get_data
 use info
 read(1,*) j,i
 allocate (supply (j))
 allocate (cost (j))
 allocate (capacity (j,i))
 allocate (demand (j,i))
 read(1,*) supply
 read(1,*) cost
 read(1,*) capacity
 read(1,*) demand
end subroutine

Subroutine SortCost
 use info
 integer u
 !u=cost(1)
 !...
 print*, cost
End subroutine

Subroutine Sortsupply
 use info
 integer u
 !u=supply(1)
 !...
 print*, supply
End subroutine

Subroutine ratecapacity
 use info
 integer u
 !u=capacity(1,1)     
 !...
 print *, j,i
 print*, capacity
End subroutine

The example above have two subroutines sortcost and sortsupply that are equals, besides of the array that are being sorted. I realy wanted a unique subroutine to make these two tasks. I just can´t declare the right way.

The way it should be:

Program Principal
 Use Info
 open(unit=1,file="dadose6h.dat")
 call get_data
 call sort(supply)
 call sort(cost)
 call rate(capacity)
end Program

Module Info
 integer i,j
 integer, dimension (:), allocatable :: supply
 integer, dimension (:), allocatable :: cost
 integer, dimension (:,:), allocatable :: capacity
 integer, dimension (:,:), allocatable :: demand
End module info


subroutine get_data
 use info
 read(1,*) j,i
 allocate (supply (j))
 allocate (cost (j))
 allocate (capacity (j,i))
 allocate (demand (j,i))
 read(1,*) supply
 read(1,*) cost
 read(1,*) capacity
 read(1,*) demand
end subroutine

Subroutine Sort(X)
 !use info
 !i dunno how the declaration should be
 integer u
 !u=X(1)
 !...
 print*, "Sort:",X
End subroutine

Subroutine rate(X)
 !use info
 !i dunno how the declaration should be neither
 integer u
 !u=X(1,1)
 !...
 print*, "rate:", X
End subroutine

I did try some declarations but none work, these guys have a similar problem FORTRAN - allocatable array in subroutine , How to pass allocatable arrays to subroutines in Fortran, in the first the answers put the fault in the intent, but I already tried (inout,out,in) and still doesn't work. The second have a answer talking about an explicit interface but I won't do anything about the allocation status.

Note: The teachers that I ask this question usely miss this point, the question isn't about passing an allocatable array to a routine, I already can do this with the module Info, however I need to show the subroutine which.

I would realy apreciate who could write this two declarations of the subroutine. Sort (unidimensional array) and Rate(bidimensional). Or at least teach me.

Content of the dadose6h.dat file:

4 
7
1000 2000 2000 2000
100 100 100 100 
10 10 74 19
60 1 25 20
90 50 7 2
11 31 51 96
15 10 94 36
52 89 47 13
30 35 4 12
100 150 50 200
100 100 200 75
100 100 200 250
100 100 150 250
150 100 200 250
200 100 200 250
200 150 200 250
Community
  • 1
  • 1
  • Use tag fortran for all Fortran questions to get more attention. Fortran 90 is just one old version, you can add tag fortran90 instead of some other tag if your question is specific to that old version.. – Vladimir F Героям слава Feb 12 '17 at 20:57
  • Please take care when writing the question, ise capital I and put spaces after commas and full stops. It takes a lot of work to edit it. – Vladimir F Героям слава Feb 12 '17 at 21:09
  • I fear that the teachers might be right and you are insisting on a wrong design of the code. – Vladimir F Героям слава Feb 12 '17 at 21:11
  • Realy thanks for the help. But about the teachers, I think I´ve make you confused, they never say that I am insisting on a wrong design. They just take a little time to understand the core of the problem, which is: the question isn't about passing an allocatable array to a routine, I need to show the subroutine which of it. – Hugo_Hensoldt Feb 12 '17 at 22:09
  • Well they didn't say that, but it is my feeling they you are insisting on a strange way of doing things. It is all very convoluted. BTW your code is some strange non-working copy of some real code. Please supply some real code ([mcve]). You have syntax errors in the code you posted and we cannot trust you it shows what it should. – Vladimir F Героям слава Feb 13 '17 at 09:49
  • It is still difficult for me to catch the contents of the question, but is it something like this?: "SortCost()" and "SortSupply()" modify the module variables "cost" and "supply" directly (via host association), but what they do is essentially the same (i.e., the routines are quite redundant), so OP wants to unify those routines into a single one that receives a dummy variable X and pass module variables via X. But how...? – roygvib Feb 13 '17 at 12:01
  • And in the second code snippet, "Module Info" seems to be missing below "end Principal" (or end program?) – roygvib Feb 13 '17 at 13:06
  • write the redundant code as a subroutine that takes an array as an argument, then your two subroutines can essentially be wrappers that pass the appropriate array to the generic sub. – agentp Feb 13 '17 at 19:13
  • You´ve catch @roygvib , excuse me for the poorly formulated question – Hugo_Hensoldt Feb 14 '17 at 03:47
  • I've made some changes in the example, thanks again for the help. @vladimir – Hugo_Hensoldt Feb 14 '17 at 03:49
  • Thanks @agentp . You were talking about some subroutines that changes a specific array from allocatable to normal? This will make the subroutines smaller but it will still have one subroutine to every needed array. – Hugo_Hensoldt Feb 14 '17 at 03:51

1 Answers1

1

Your design is still very confusing to me. I would just do this:

Module Info
 integer i,j
 integer, dimension (:), allocatable :: supply
 integer, dimension (:), allocatable :: cost
 integer, dimension (:,:), allocatable :: capacity
 integer, dimension (:,:), allocatable :: demand
End module info


Module Procedures

contains

  Subroutine Sort(X)
   integer :: X(:)

   integer u
   !u=X(1)
   !...
   print*, "Sort:",X
  End subroutine

End module Procedures


Program Principal
 Use Info
 Use Procedures

 open(unit=1,file="dadose6h.dat")
 call get_data
 call sort(supply)
 call sort(cost)
 call rate(capacity)
end Program

That is a very small change, so it is possible that I don't understand your description. I don't see any reason why the sorting procedure should require the module with the data.

  • The example doesn't have any reason to use the module data, but the original problem had. I've made some changes so the sort routine example has that reason(print*,i). Thanks for the answer, It helped a lot. – Hugo_Hensoldt Feb 14 '17 at 15:43