views:

227

answers:

4

Hello,

I have the following FORTRAN code which I need to convert to C or C++. I already tried using f2c, but it didn't work out. It has something to do with conversion from Lambert Conformal wind vector to a True-North oriented vector. Is anyone experienced in FORTRAN who could possibly help?

PARAMETER ( ROTCON_P   =  0.422618      )
PARAMETER ( LON_XX_P   = -95.0          )
PARAMETER ( LAT_TAN_P  =  25.0          )

    do j=1,ny_p
    do i=1,nx_p
       angle2 = rotcon_p*(olon(i,j)-lon_xx_p)*0.017453
       sinx2 = sin(angle2)
       cosx2 = cos(angle2)
     do k=1,nzp_p
       ut = u(i,j,k)
       vt = v(i,j,k)   
       un(i,j,k) = cosx2*ut+sinx2*vt
       vn(i,j,k) =-sinx2*ut+cosx2*vt
      end if
     end do
    end do

Thanks a lot for any help or tip.

A: 

With so short and simple a code, why would you not just do it by hand?

Any fortran book from after about 1985 should cover the language in use here.

dmckee
+2  A: 

This will get you started - I didn't try to compile it, but it's close to what you're going to need. I assumed that the arrays olon, u, v, un, and vn are passed in to your function as pointers.

const double rotcon_p   =  0.422618;
const double lon_xx_p   = -95.0;
const double lat_tan_p  =  25.0;

for (j=0;j<ny_p;++j)
{
  for (i=0,i<nx_p;++i)
  {
    double angle2 = rotcon_p*(olon[i][j]-lon_xx_p)*0.017453;
    double sinx2 = sin(angle2);
    double cosx2 = cos(angle2);
    for (k=0;k<nsp_p;++k)
    {
      double ut = u[i][j][k]
      double vt = v[i][j][k]
      un[i][j][k] = cosx2*ut+sinx2*vt
      vn[i][j][k] =-sinx2*ut+cosx2*vt
   }
  }
}

If you're staying completely in c/c++ this will be fine, if you're mixing FORTRAN and c/c++, you need to know that FORTRAN and c/c++ index their arrays backwards, so you may have to swap your indices to make it work

const double rotcon_p   =  0.422618;
const double lon_xx_p   = -95.0;
const double lat_tan_p  =  25.0;

for (j=0;j<ny_p;++j)
{
  for (i=0,i<nx_p;++i)
  {
    double angle2 = rotcon_p*(olon[j][i]-lon_xx_p)*0.017453;
    double sinx2 = sin(angle2);
    double cosx2 = cos(angle2);
    for (k=0;k<nsp_p;++k)
    {
      double ut = u[k][j][i]
      double vt = v[k][j][i]
      un[k][j][i] = cosx2*ut+sinx2*vt
      vn[k][j][i] =-sinx2*ut+cosx2*vt
   }
  }
}

But I don't have enough context for your problem to tell you which you need to do.

miked
It's also worth noting that his arrays use 1 and n for the start-index and end-index, respectively, instead of 0 and n-1. This is not unusual in FORTRAN, of course.
Ben Hocking
yes, that's why I changed the for loops so that the data being referenced would be the same.
miked
+1  A: 

I speak Fortran as well as Tarzan speaks English, but this should be the gist of it in C:

#include <math.h>

const double ROTCON_P = 0.422618;
const double LON_XX_P = -95.0;
const double LAT_TAN_P = 25.0;

int i, j, k;
double angle2, sinx2, cosx2, ut, vt;
double un[nzp_p][ny_p][nx_p];
double vn[nzp_p][ny_p][nx_p];

for (j=0; j<ny_p; ++j) {
    for (i=0; i<nx_p; ++i) {
        angle2 = ROTCON_P * (olon[j][i] - LON_XX_P) * 0.017453;
        sinx2 = sin(angle2);
        cosx2 = cos(angle2);
        for (k=0; k<nzp_p; ++k) {
            ut = u[k][j][i];
            vt = v[k][j][i];
            un[k][j][i] = (cosx2 * ut) + (sinx2 * vt);
            vn[k][j][i] = (-1 * sinx2 * ut) + (cosx2 * vt);
        }
    }
}

You will need to declare olon, u, v, nx_p, ny_p, and nzp_p somewhere and assign them a value before running this code. There is not enough context info given for me to know exactly what they are.

bta
A: 

This is a fragment of code, which may be why f2c didn't work. Plus, as already pointed out, most likely the "end if" should be "end do".

If you have Fortran subroutines that are tested and do the calculation that you need, you can call them from C. You declare the arguments of the Fortran subroutine using the ISO C Binding of Fortran, then the Fortran compiler will use the C API so that the routine is callable from C. This short code block is easy to translate; something long and complicated might be better to reuse.

M. S. B.