Fortran project

19 views
Skip to first unread message

Dominik Böttcher

unread,
May 4, 2019, 4:00:41 AM5/4/19
to f2py users
Dear All,

i am a PhD student who is combining a diffusion model which i wrote in python myself with a chemical properties model from my chair. The property model is written in FORTRAN 77 and should recieve input variables from the diffusion model and output some variables to the diffusion model. The property model is a big fortran project which is written as a program, reading inputs from the user via the console and outputs the results as a .txt file.
Now to my question, is it possible to convert a whole program via F2PY to python or do i need to locate and load the relevant subroutines individually? Or would it be smarter to write the diffusion model in fortran. Thanks for any help.

a nice day wishes,

Dominik

Dr. Louis Wicker

unread,
May 6, 2019, 11:54:05 AM5/6/19
to Dominik Böttcher, f2py users
Dominik,

I have used f2py extensively in my work (modeling, and ensemble Kalman filtering for atmospheric models).  You do not have to interface python to all the fortran routines, just the 1 or 2 that have to interact with input.  The rest can be added to the compile as “*.o" files.  So for input parameters from python (suppose you want to be able to use command line input using one of the Parser modules in Python), you would pass parameters from python through to the fortran.  So your fortran “main” program becomes a fortran subroutine that Python calls.  If that “main” routine also writes out the txt file, you can pass an array or whatever back through on exit from the fortran to python automatically and then do more stuff in python (plotting, writing netCDF, etc) with the data passed back.

The easiest way to interface automatically is to write the subroutine that interaces with python using INTENT arguments…. Here is an example of a 2D analysis in fortran from scattered data.  The cressman routine does the analysis and returns a 2D array.  Below the code is my line to compile this code, and then the line that calls it within a python rouytine.  The fortran is in F90, but one can use F77…...


subroutine cressman(x, y, ob, xg, yg, method, min_count, min_weight, min_range, roi, missing_value, anal, nobs, nx, ny)

   implicit none

   real(8), intent(in),  dimension(nobs) :: x
   real(8), intent(in),  dimension(nobs) :: y
   real(4), intent(in),  dimension(nobs) :: ob
   real(8), intent(in),  dimension(nx)   :: xg
   real(8), intent(in),  dimension(ny)   :: yg
   real(4), intent(out), dimension(nx,ny) :: anal
   real,    intent(in) :: roi, missing_value, min_weight, min_range
   integer, intent(in) :: nobs, nx, ny, min_count, method

   integer n, i, j, count
   real(kind=8) dis, R2, w_sum, sum, wk, rk2
   real, parameter :: hsp0 = 1.33

   logical, parameter :: debug = .true.

   IF ( method .eq. 1 ) THEN
     R2 = roi**2.0
   ELSE
     R2 = (hsp0*roi/1000.)**2     ! Pauley and Wu (1990)
   ENDIF

   IF( debug ) THEN
      print *, 'Method:                 ', method
      print *, 'Min gates for analysis: ', min_count
      print *, 'Min weight for analysis:', min_weight
      print *, 'Min range for analysis: ', min_range
      print *, 'Nobs:                   ', nobs
      print *, 'Nx/Ny:                  ', nx, ny
      print *, 'Maxval of anal before:  ', maxval(anal)
      print *, 'Minval of anal before:  ', minval(anal)
      print *, ''
      print *, 'Maxval of observations:  ', maxval(ob)
      print *, 'Minval of observations:  ', minval(ob)
      print *, 'Min/Max xob:    ', minval(x), maxval(x)
      print *, 'Min/Max yob:    ', minval(y), maxval(y)
      print *, 'Min/Max xgrid:  ', minval(xg), maxval(xg)
      print *, 'Min/Max ygrid:  ', minval(yg), maxval(yg)
      print *, 'Radius of influence:  ', roi
      print *, ''
   ENDIF

   DO j = 1,ny
    DO i = 1,nx

     IF( method .eq. 1 ) THEN   ! Cressman

       count = 0
       w_sum = 0.0
       sum   = 0.0
       anal(i,j) = missing_value
       DO n = 1,nobs
         dis = sqrt( (xg(i) - x(n))**2 + (yg(j)-y(n))**2 )
         IF ((dis .le. roi) .and. (dis .ge. min_range)) THEN
           rk2 = dis**2.0
           wk = (R2-rk2) / (R2+rk2)
           sum = sum + wk*ob(n)
           w_sum = w_sum + wk
           count = count + 1
         ENDIF
       ENDDO

     ELSE       ! Barnes 1-pass

       count = 0
       w_sum = 0.0
       sum   = 0.0
       anal(i,j) = missing_value
       DO n = 1,nobs
         dis = sqrt( (xg(i) - x(n))**2 + (yg(j)-y(n))**2 )
         IF ((dis .le. 6.0*roi) .and. (dis .ge. min_range)) THEN
           rk2 = dis**2.0
           wk = exp( -rk2 / R2 )
           sum = sum + wk*ob(n)
           w_sum = w_sum + wk
           count = count + 1
         ENDIF
       ENDDO

     ENDIF


     IF ((w_sum .ge. min_weight) .and. (count .ge. min_count)) THEN
        anal(i,j) = anal(i,j) + sum/w_sum
     ENDIF

    ENDDO
   ENDDO

   IF( debug ) THEN
      print *, 'Maxval of anal after:  ', maxval(anal)
      print *, 'Minval of anal after:  ', minval(anal)
   ENDIF

 end subroutine cressman

---------------COMPILE--------

#!/usr/bin/env python

import os

# remove all module files in directory - this can trip you up bad!

print "\n=====================================================\n"
print("   ---> Compiling...")
print "\n=====================================================\n"

cmd = "f2py --fcompiler='gnu95' --f90flags='-O3' -c -m cressman cressman.f90"
os.system(cmd)

------------PYTHON
.
.
.

anal2d = cressman.obs_2_grid2d(obs, xob, yob, xg, yg, ix, iy, anal_method, min_count, min_weight, min_range, \
                                       2.0*grid_spacing_xy, _missing)

—> notice that anal array is NOT in the  python call to the subroutine.  The INTENT(OUT) in the fortran declarations 
makes the array a returned pointer to the 2D numpy array within python, so you omit it from the call list from python, even though its in the fortran subroutine call.

HTH,

Lou Wicker



--
You received this message because you are subscribed to the Google Groups "f2py users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to f2py-users+...@googlegroups.com.
Visit this group at https://groups.google.com/group/f2py-users.
For more options, visit https://groups.google.com/d/optout.

----------------------------------------------------------------------------
| Dr. Louis J. Wicker
| NSSL/FRDD  Rm 3336
| National Weather Center
| 120 David L. Boren Boulevard, Norman, OK 73072
|
| E-mail:   Louis....@noaa.gov
| HTTP:    www.nssl.noaa.gov/~lwicker
| Phone:    (405) 325-6340
| Fax:        (405) 325-2316
|
----------------------------------------------------------------------------
|
|  “If we can forgive what's been done to us… 
|  If we can forgive what we've done to others… 
|  If we can leave our stories behind. Our being victims and villains. 
|  Only then can we maybe rescue the world.”
|
|       — Chuck Palahniuk
|
----------------------------------------------------------------------------
|
| "The contents  of this message are mine personally and 
| do not reflect any position of  the Government or NOAA.”
|
|---------------------------------------------------------------------------











Dominik Böttcher

unread,
May 7, 2019, 8:35:40 AM5/7/19
to f2py users
Dear Dr. Louis J. Wicker,

thank you very much for the valuable information based on your experience on similar projects. These and the example code should be sufficient to guide my plans. I will continue to disect the fortran project and find the files which act as"ports" for my inputs and outputs.

Best regards,

Dominik

Reply all
Reply to author
Forward
0 new messages