1

I'm working on a project, where the results of a numerical simulation program are to be optimized to fit measured behavior. I wrote some freeform Fortran routines to extract specific data and perform some preliminary calculations, which work fine. For the optimization purpose, i plan to use a local search algorithm provided here: http://mat.uc.pt/~zhang/software.html#bobyqa

I pass some arguments like dimensions and parameter vectors into the Fortran 77 routine, and the problem is, that the transferred argument arrays don't reach the other side. Only the first element will show up in an array with dimension 1.

I found some helpful answers in How to use Fortran 77 subroutines in Fortran 90/95? and tried to contain all 77 code in a module but i still don't get it done. An explicit interface helps to get all variables into level1 f77 subroutine, but when stuff is beeing passed to another (level2), where assumed size arrays are to be constructed, 1-dimensional arrays are generated if at all.

I compile the f77 code first using ifort -c -fixed (and tried -f77rtl), then f90 and link all together.

Why are the assumed size arrays not generated properly?? The test program from vendor works fine!

How can i pass all needed data through and back in a defined way, without using explicit interfaces? Or is there a way to define suitable interfaces?

Here some example code:

  program main_f90
     use types
     implicit none
     real(dp) :: array(N)

     interface 
        subroutine sub77_level1(array)
           implicit real*8 (a-h,o-z)
           real*8, intent(inout) :: array
           dimension array(:)
        end subroutine
     end interface

     [...fill array...]
     call sub77_level1(array)
  end


  subroutine sub77_level1(array)
     implicit real*8 (a-h,o-z)
     integer i1, i2, i3, i4
     dimension array(:)

     [...modify array...]

     call sub77_level2(array(i1), array(i2), array(i3), i4)
     return
  end


  subroutine sub77_level2(array_1, array_2, array_3, i4)
     implicit real*8 (a-h,o-z)
     dimension array_1(*) array_2(*) array_3( i4, * )

     [...modify...]
     call sub_f90( <some other arrays, intent(in / out)> )

     return
  end
cclem
  • 11
  • 2
  • 1
    It would help o see the actual errors you gat. I really don't get much from *"but when stuff is beeing passed to another (level2), where assumed size arrays are to be constructed, 1-dimensional arrays are generated if at all."*. You should show the expected output and the actual output and be able to tell us what you think is wrong about the output. – Vladimir F Героям слава Jan 26 '16 at 15:41
  • I can't see any `i4` in the `sub77_level2` argument list. Where does it come from there. Do you have any particular reason not to use `implicit none`? Is it the actual code you have (you *should* show as one)? Be sure to compile with `-g -warn -check -traceback`. – Vladimir F Героям слава Jan 26 '16 at 15:43
  • 1
    The procedure `sub77_level1` uses assumed shape arrays (the `(:)` dimension specification). That's not Fortran 77 - that's at least Fortran 90. The use of that assumed shape dummy argument is why that procedure needs an interface body in the calling scope. (There is a mismatch in INTENT specification between the interface body for that procedure and the subprogram for the procedure.) – IanH Jan 26 '16 at 19:31
  • "How can i pass all needed data through and back in a defined way, without using explicit interfaces? Or is there a way to define suitable interfaces?" Answer: put your procedures into modules. Reasons to use interfaces are if you don't have the source code, or if its in a different language. Otherwise modules are easier and better. See http://stackoverflow.com/questions/8412834/correct-use-of-modules-subroutines-and-functions-in-fortran – M. S. B. Jan 27 '16 at 01:43
  • The actual error, that occurs would not help much: two of the passed arrays contain upper and lower bounds, the f77 routine checks, if their difference remains big enough to work. If not, it prints to console, that the bounds are wrong. When debugging the code, the reason is obviously the missing entries in the wrongly created 1-d arrays. Expected would be upper_bounds(6) and lower_bounds(6) but both only contain 1 entry – cclem Jan 27 '16 at 08:13
  • i missed it, its fixed now – cclem Jan 27 '16 at 08:20
  • the interface as shown was my only successful try to get the full arrays into level 1, so thats not the original design any more. You suggest, to leave the f77 code untouched, remove the interfaces, and put all f77 code into modules? Or just the top level subroutine, which calls further f77 code? – cclem Jan 27 '16 at 08:26
  • Is `sub77_level1` the entry point to bobyqa? – why.n0t Jan 27 '16 at 10:37
  • Thats right, i tried to avoid sharing someone elses code here, since i'm not sure if that was legal... – cclem Jan 27 '16 at 10:50
  • bobyqa is free. (GNU Lesser General Public License) What is sub77_level2? And did you alter the calling arguments? – why.n0t Jan 27 '16 at 11:51
  • OK i put all untouched f77 bobyqa code into one module file, wrapping around `MODULE BOB ; IMPLICIT REAL*8 (A-H,O-Z) ; PRIVATE ; PUBLIC BOBYQA ; CONTAINS ; [...Subroutines...] ; END MODULE` but the same problem occurs, assumed size arrays are 1-d. Maybe my module header is wrong? Compilation is done in windows using `ifort -c bob_module.f -debug:full -check:all -fixed -f77rtl` . Module first, then linking with `ifort -o program.exe $(OBJECTS) bob_module.obj -debug:full -check:all` – cclem Jan 27 '16 at 11:55
  • level2 is subroutine bobyqB, which then calls f77 subroutines altmov, prelim, update, rescue, trsbox and calfun (where i want to place my f90 quality functional subroutine). I did not change any arguments – cclem Jan 27 '16 at 12:00
  • i didn't used any modules, i had all bobyq subroutines in the same source file as my code. I used Fortran 90/95 but in fixed format. (it's a mess, but it works and doesn't have to be maintainable). – why.n0t Jan 27 '16 at 12:31
  • Using modules helped to repair the flow of data from f90 through f77 to f90 subroutines and back again and the program works now. But i had to eliminate all assumed-size definitions by firstly calculating the lengths of my arrays and then additionally pass these to the subroutines, where fixed size arrays are defined. Thanks for all of your efforts! – cclem Jan 27 '16 at 15:56

0 Answers0