Graphics: NCL - Linking to Fortran Code

It is possible to link your favorite FORTRAN diagnostics routines to NCL.
It is easier to use FORTRAN 77 code, but NCL does recognize basic FORTRAN 90 code.

Adding diagnostics using FORTRAN 77 code
Adding diagnostics using FORTRAN 90 code
 


Adding diagnostics using FORTRAN 77 code

Let’s use a routine that calculates temperature (K) from theta and pressure.

FORTRAN 90 routine called myTK.f90

subroutine compute_tk (tk,pressure,theta, nx, ny, nz)
implicit none

!! Variables
    integer  :: nx,ny,nz
    real, dimension (nx,ny,nz) :: tk, pressure, theta

!! Local Variables
    integer :: i,j,k
    real, dimension (nx,ny,nz):: pi
           
    pi(:,:,:) = (pressure(:,:,:) / 1000.)**(287./1004.)
    tk(:,:,:) = pi(:,:,:)*theta(:,:,:)
 
return
end subroutine compute_tk

 

For simple routines like this, it is easiest to re-write the routine into a FORTRAN 77 routine.

FORTRAN 77 routine called myTK.f

        subroutine compute_tk (tk,pressure,theta, nx, ny, nz)
        implicit none

C     Variables
        integer  nx,ny,nz
        real  tk(nx,ny,nz)
        real  pressure(nx,ny,nz), theta(nx,ny,nz)

C     Local Variables
        integer  i,j,k
        real   pi

        DO k=1,nz
          DO j=1,ny 
            DO i=1,nx        
               pi=(pressure(i,j,k) / 1000.)**(287./1004.)
               tk(i,j,k) = pi*theta(i,j,k)
            ENDDO
          ENDDO
        ENDDO

      return
      end

 

Add the markers NCLFORTSTART and NCLEND to the subroutine as indicated below.
Note, that local variables are outside these block markers.

FORTRAN 77 routine called myTK.f, with NCL markers added

C NCLFORTSTART
        subroutine compute_tk (tk,pressure,theta, nx, ny, nz)
        implicit none

C     Variables
        integer  nx,ny,nz
       
        real  tk(nx,ny,nz)
        real  pressure(nx,ny,nz), theta(nx,ny,nz)

C NCLEND

C     Local Variables
        integer  i,j,k
        real   pi

        DO k=1,nz
          DO j=1,ny 
            DO i=1,nx        
               pi=(pressure(i,j,k) / 1000.)**(287./1004.)
               tk(i,j,k) = pi*theta(i,j,k)
            ENDDO
          ENDDO
        ENDDO

      return
      end

 

Now compile this code using the NCL script WRAPIT:

WRAPIT myTK.f

NOTE: If WRAPIT cannot be found, make sure the environment variable NCARG_ROOT has been set correctly.

If the subroutine compiles successfully, a new library will be created (called myTK.so).
This library can be linked to an NCL script to calculate TK. See how this is done in the example below:

load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"       
load "$NCARG_ROOT/lib/ncarg/nclscripts/wrf/WRFUserARW.ncl”
external myTK "./myTK.so"          

begin

       t = wrf_user_getvar (a,”T”,5)
       theta = t + 300
       p = wrf_user_getvar (a,”pressure”,5)

       dim = dimsizes(t)
       tk = new( dimsizes(t), typeof(t) )

       myTK::compute_tk(tk,p,theta,dim(2),dim(1),dim(0))

end

--- top ---


Adding diagnostics using FORTRAN 90 code

If you are interested in using the FORTRAN 90 program, it is possible to do so by providing an interface block for your FORTRAN 90 program. Your FORTRAN 90 program cannot contain any of the following features:

  • pointers or structures as arguments,
  • missing/optional arguments,
  • keyword arguments, or
  • if the procedure is recursive.

Let’s use a routine that calculates temperature (K) from theta and pressure.

FORTRAN 90 routine called myTK.f90

subroutine compute_tk (tk,pressure,theta, nx, ny, nz)
implicit none

!! Variables
    integer  :: nx,ny,nz
    real, dimension (nx,ny,nz) :: tk, pressure, theta

!! Local Variables
    integer :: i,j,k
    real, dimension (nx,ny,nz):: pi
           
    pi(:,:,:) = (pressure(:,:,:) / 1000.)**(287./1004.)
    tk(:,:,:) = pi(:,:,:)*theta(:,:,:)
 
return
end subroutine compute_tk

 

Create an interface for your FORTRAN 90 program.

Interface block for FORTRAN 90 code, called myTK90.stub

C NCLFORTSTART
        subroutine compute_tk (tk,pressure,theta, nx, ny, nz)

        integer  nx,ny,nz
        real  tk(nx,ny,nz)
        real  pressure(nx,ny,nz), theta(nx,ny,nz)

C NCLEND

Now compile this code using the NCL script WRAPIT.

WRAPIT myTK90.stub myTK.f90

NOTE: You may need to copy the WRAPIT script to a location and edit it to point to a FORTRAN 90 compiler.

If the subroutine compiles successfully, a new library will be created (called myTK90.so ).
This library can be linked to an NCL script to calculate TK. See how this is done in the example below:

load"$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"       
load "$NCARG_ROOT/lib/ncarg/nclscripts/wrf/WRFUserARW.ncl”
external myTK90 "./myTK90.so"  

begin

       t = wrf_user_getvar (a,”T”,5)
       theta = t + 300
       p = wrf_user_getvar (a,”pressure”,5)

       dim = dimsizes(t)
       tk = new( dimsizes(t), typeof(t) )

       myTK90::compute_tk(tk,p,theta,dim(2),dim(1),dim(0))

end

--- top ---