简体   繁体   English

需要将以下FORTRAN代码转换为C ++

[英]Need to convert following FORTRAN code to C++

Im a very poor programmer, and i was given a program to supposedly help me on my aerodynamic hw. 我是一个非常糟糕的程序员,并且给了我一个程序,可以帮助我进行空气动力学方面的研究。 but its in fortran, and im trying to use MATLAB to run this program. 但它在fortran中,并且我试图使用MATLAB运行该程序。 any help on converting it to a language matlab understands? 将其转换为Matlab可以理解的语言有什么帮助吗? (preferabbly c++) (最好是c ++)

      program joukow
c

c   computes joukowski airfoil and finds pressure coefficient

c   currently set up for symmetric airfoil with sharp trailing edge

c   and chord length equal to one.

c   profile is written onto prof.dat and cp onto cp.dat

c      implicit real*8(a-h,o-z)

      complex z,zeta,cw
      dimension uz(100),vz(100),xi(100),eta(100),cp(100)
      dimension xout(100),yout(100)
         open(unit=8,file='prof.dat',status='unknown')
         open(unit=9,file='cp.dat',status='unknown')
      b=1.d0
      write(6,98)
      format(2x,'input the radius of the a-circle in z plane')
      read(5,99)a
      format(f10.0)
      xl=2.*a-1.+1./(2.*a-1.)

c      xl=a+1./a

c      chord=2.*xl

      chord=2.+xl
      del=a-b

c      del =0.1d0
      do 50 i=1,100
      ri=i
      theta=6.2832d0*ri/101.d0
      x=-del+a*cos(theta)
      y=a*sin(theta)
      z=cmplx(x,y)
      zeta=z+b**2/z

c

c  xi and eta are coordinates of points on airfoil

c

      xi(i)=real(zeta)

      eta(i)=aimag(zeta)

      cw=(1.-a**2/(z+del)**2)/(1.-b**2/z**2)
c

c  uz and vz are velocity components on the airfoil assuming the free-stream

c  speed is one.
c
      uz(i)=real(cw)
      vz(i)=-aimag(cw)

c

c  xout and yout are airfoil coordinates where the leading edge is at (0,0)

c  and the chordlength is one.

c

      xout(i)=(xl+xi(i))/chord
      yout(i)=eta(i)/chord
      write(8,100)xout(i),yout(i)
      format(2x,2f10.4)
      continue

c

c  now calculate the pressure coefficient cp

c

      write(6,200)
      format(2x,'pressure coefficients')
      do 70 i=1,50
      cp(i)=1.-(uz(i)**2+vz(i)**2)
      write(9,100)xout(i),cp(i)
      continue
      stop
      end

Matlab understands Fortran just fine -- check the documentation. Matlab理解Fortran很好-检查文档。 And if that doesn't satisfy you, most of the lines in the program which do any computation could be typed into the Matlab console with very little modification. 而且,如果这不满足您的要求,则只需进行很少的修改即可将程序中执行任何计算的大多数行键入到Matlab控制台中。 If you are a poor programmer, I suggest that you spend your time modifying the program into Matlab rather than into C++. 如果您是一个贫穷的程序员,我建议您花时间将程序修改为Matlab而不是C ++。 I'll write more later if you don't get any better help than I have time for right now. 如果您没有比我现在有时间的更好的帮助,我会在以后再写更多。

EDIT: first off, some information on using Fortran source files from Matlab. 编辑:首先,关于从Matlab 使用Fortran源文件的一些信息。 If you really don't want to (or can't or have performance reasons for not doing so) rewrite the Fortran into Matlab then turn it into a MEX file. 如果您真的不想(或出于性能原因或不这样做的话)将Fortran重写为Matlab,然后将其转换为MEX文件。 Using f2c (or anything else, including your own time and effort) to first translate the Fortran into C or C++ seems pointless to me. 对我来说,使用f2c(或其他任何方式,包括您自己的时间和精力)将Fortran转换为C或C ++似乎毫无意义。

If you don't like that idea, here are some ideas on turning Fortran into Matlab. 如果您不喜欢该想法,这里有一些将Fortran转换为Matlab的想法。

First, all lines beginning with C or c are comments so you don't need to translate them. 首先,所有以C或c开头的行都是注释,因此您无需翻译它们。 Start with your code: 从您的代码开始:

  complex z,zeta,cw
  dimension uz(100),vz(100),xi(100),eta(100),cp(100)
  dimension xout(100),yout(100)

These lines declare a number of variables. 这些行声明了许多变量。 You don't have to declare variables before you use them in Matlab but, there are sometimes good reasons to do so. 您不必在Matlab中使用变量之前就声明变量,但是有时有充分的理由这么做。 You don't have to in Fortran either, though this is universally considered a bad idea these days. 您也不必在Fortran中使用,尽管如今普遍认为这是个坏主意。 You could 'declare' these variables in Matlab with statements such as: 您可以使用以下语句在Matlab中“声明”这些变量:

uz = zeros(100,1); 
vz = zeros(100,1);

By declaring these in advance in your Matlab you allocate memory for them once, and avoid some performance-reducing problems. 通过在Matlab中预先声明它们,可以为它们分配一次内存,并避免一些降低性能的问题。

The next 2 lines: 接下来的2行:

     open(unit=8,file='prof.dat',status='unknown')
     open(unit=9,file='cp.dat',status='unknown')

open a couple of files for output. 打开几个文件进行输出。 They are used later in write statements - forget them, write Matlab statements such as save xout instead. 它们稍后将在write语句中使用-忘记它们,而改写Matlab语句,例如save xout

The next line is Fortran but identical in Matlab: 下一行是Fortran,但在Matlab中相同:

  b=1.d0

The next lines get a value for the radius from the console: 接下来的几行从控制台获取半径值:

  write(6,98)
  format(2x,'input the radius of the a-circle in z plane')
  read(5,99)a
  format(f10.0)

again, I suggest you forget these, just use the Matlab console to set the value of a . 再次,我建议你忘记了这些,只需要使用Matlab的控制台设置的值a More Fortran that doesn't need to be translated (though I suggest you either drop the decimal points without following 0s or put a space between them and the subsequent * -- .* is a specific operator in Matlab): 更多不需要翻译的Fortran(尽管我建议您要么舍弃小数点后不跟0,要么在它们之间加上空格,随后的*-。*是Matlab中的特定运算符):

  xl=2.*a-1.+1./(2.*a-1.)

  chord=2.+xl
  del=a-b

A Fortran do loop is the same as a Matlab for loop. Fortran do循环与Matlab for循环相同。 Rewrite: 改写:

  do 50 i=1,100

as

for i = 1:100

As one of the other respondents has noted it's not clear where the matching end statement goes, you'll have to figure that out. 正如其他受访者中的一位指出的那样,匹配的结束语句不明确,您必须弄清楚这一点。 Note that I'm just offering a line-by-line translation of Fortran into Matlab. 请注意,我只是提供Fortran到Matlab的逐行翻译。 It's not well-written Fortran, and I'm not offering well-written Matlab, I'll leave that to you. 它不是写得很好的Fortran,而且我也没有提供写得很好的Matlab,我会留给您。

This lot doesn't need to be translated: 这很多不需要翻译:

  ri=i
  theta=6.2832d0*ri/101.d0 
  x=-del+a*cos(theta)
  y=a*sin(theta)

cmplx is a Fortran function which returns a complex number which has real part x and imaginary part y: cmplx是一个Fortran函数,它返回一个复数,该复数具有实部x和虚部y:

  z=cmplx(x,y)

In Matlab this would be z = x + y * i. 在Matlab中,这将是z = x + y * i。 Fortran uses ** for exponentiation, Matlab uses ^ Fortran使用**进行幂运算,Matlab使用^

  zeta=z+b**2/z

and so on and so on. 等等等等。

Hope that helps. 希望能有所帮助。

I used f2matlab and a little touching up afterward. 我使用了f2matlab,然后稍加修饰。 Here is the cleaned up and compilable fortran90 code: 这是经过整理和编译的fortran90代码:

program joukow
 !
 !   computes joukowski airfoil and finds pressure coefficient
 !   currently set up for symmetric airfoil with sharp trailing edge
 !   and chord length equal to one.
 !   profile is written onto prof.dat and cp onto cp.dat
 !      implicit real*8(a-h,o-z)
 complex z,zeta,cw
 dimension uz(100),vz(100),xi(100),eta(100),cp(100)
 dimension xout(100),yout(100)
 open(unit=8,file='prof.dat',status='unknown')
 open(unit=9,file='cp.dat',status='unknown')
 b=1.d0
 write(6,98)
98 format(2x,'input the radius of the a-circle in z plane')
 read(5,99)a
99 format(f10.0)
 xl=2.*a-1.+1./(2.*a-1.)
!      xl=a+1./a
!      chord=2.*xl
 chord=2.+xl
 del=a-b
!      del =0.1d0
 do i=1,100
  ri=i
  theta=6.2832d0*ri/101.d0
  x=-del+a*cos(theta)
  y=a*sin(theta)
  z=cmplx(x,y)
  zeta=z+b**2/z
  !
  !  xi and eta are coordinates of points on airfoil
  !
  xi(i)=real(zeta)
  eta(i)=aimag(zeta)
  cw=(1.-a**2/(z+del)**2)/(1.-b**2/z**2)
  !
  !  uz and vz are velocity components on the airfoil assuming the free-stream
  !  speed is one.
  !
  uz(i)=real(cw)
  vz(i)=-aimag(cw)
  !
  !  xout and yout are airfoil coordinates where the leading edge is at (0,0)
  !  and the chordlength is one.
  !
  xout(i)=(xl+xi(i))/chord
  yout(i)=eta(i)/chord
  write(8,100)xout(i),yout(i)
100 format(2x,2f10.4)
 end do
!
!  now calculate the pressure coefficient cp
!
 write(6,200)
200 format(2x,'pressure coefficients')
 do  i=1,50
  cp(i)=1.-(uz(i)**2+vz(i)**2)
  write(9,100) xout(i),cp(i)
 end do
 stop
end program joukow

Here is the resulting matlab code: 这是生成的matlab代码:

function hw1(varargin)
%
%   computes joukowski airfoil and finds pressure coefficient
%   currently set up for symmetric airfoil with sharp trailing edge
%   and chord length equal to one.
%   profile is written onto prof.dat and cp onto cp.dat
%      implicit real*8(a-h,o-z)

format_99=['%10.0f'];
format_100=[repmat(' ',1,2),repmat('%10.4f',1,2),'\n'];
format_200=[repmat(' ',1,2),'pressure coefficients \n'];

fid_8=fopen('prof.dat','w+');
fid_9=fopen('cp.dat','w+');
b=1.0d0;
a=input('input the radius of the a-circle in z plane');
xl=2..*a-1.+1../(2..*a-1.);
%      xl=a+1./a
%      chord=2.*xl
chord=2.+xl;
del=a-b;
%      del =0.1d0
for i=1:100;
 ri=i;
 theta=6.2832d0.*ri./101.0d0;
 x=-del+a.*cos(theta);
 y=a.*sin(theta);
 z=complex(x,y);
 zeta=z+b.^2./z;
 %
 %  xi and eta are coordinates of points on airfoil
 %
 xi(i)=real(zeta);
 eta(i)=imag(zeta);
 cw=(1.-a.^2./(z+del).^2)./(1.-b.^2./z.^2);
 %
 %  uz and vz are velocity components on the airfoil assuming the free-stream
 %  speed is one.
 %
 uz(i)=real(cw);
 vz(i)=-imag(cw);
 %
 %  xout and yout are airfoil coordinates where the leading edge is at (0,0)
 %  and the chordlength is one.
 %
 xout(i)=(xl+xi(i))./chord;
 yout(i)=eta(i)./chord;
 fprintf(fid_8,format_100,xout(i),yout(i));
end; i=100+1;
%
%  now calculate the pressure coefficient cp
%
fprintf(1,format_200);
for  i=1:50;
 cp(i)=1.-(uz(i).^2+vz(i).^2);
 fprintf(fid_9,format_100, xout(i),cp(i));
end;  i=50+1;
end %program joukow

They both give the same results for me. 他们都给我相同的结果。 I didn't check the algorithm for correctness, though, just converted the code. 我没有检查算法的正确性,只是转换了代码。

我不知道它的支持程度如何--但是以前最简单的方法是f2c,它可以将fortran直接转换为c代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM