Google Answers Logo
View Question
 
Q: FORTRAN program conversion and syntax inquiry ( Answered 5 out of 5 stars,   1 Comment )
Question  
Subject: FORTRAN program conversion and syntax inquiry
Category: Computers > Programming
Asked by: oogle-ga
List Price: $9.50
Posted: 13 May 2003 23:11 PDT
Expires: 12 Jun 2003 23:11 PDT
Question ID: 203475
Hi, I have a really old numerical methods math book here with FORTRAN
code inside.  I found one FORTRAN program that I would like to convert
to Java.  My programming experience is not exceptionally broad, I have
only done coding mainly in Java and C++.  I am hoping if someone can
help me with this program, and get me to understand each parts of the
FORTRAN syntax.  Here I have wrote down the FORTRAN code from the
book:

================================================================

	PROGRAM EXPLPA (INPUT,OUPUT)
C
C  ------------------------------------------------------------------
C
C  THIS PROGRAM COMPUTES ONE DIMENSIONAL UNSTEADY STATE POTENTIAL
C  FLOW PROBLEMS BY THE EXPLICIT METHOD.  THE POTENTIAL AT EACH END
C  IS SPECIFIED AS A FUNCTION OF TIME THROUGH ARITHMETIC STATEMENT
C  FUNCTIONS.
C
C  ------------------------------------------------------------------
C
C        PARAMETERS ARE :
C
C	U, V	-	VALUES OF THE POTENTIAL AT NODES
C	T	-	TIME
C	TF	-	FINAL TIME FOR WHICH VALUES ARE COMPUTED
C	DT	-	DELTA T
C	LEN	-	LENGTH
C	DX	-	DELTA X
C	N	-	NUMBER OF X INTERVALS
C	K	-	CONDUCTIVITY
C	C	-	HEAT CAPACITY
C	RHO	-	DENSITY
C	RATIO	-	RATIO OF (K (DT)) / (C * (RHO) * ((DX) ^ 2))
C
C	FLFT	-	BOUNDARY CONDITION ON LEFT END
C	FRT	-	BOUNDARY CONDITION ON RIGHT END
C  ------------------------------------------------------------------
C
	REAL U (500), V(500), LEN, K, T, TF, DT, DX, C, RHO, THALF, RATIO
	INTEGER N, NP1, I
C
C  ------------------------------------------------------------------
C
C  WE DEFINE SOME CONSTANTS WITH A DATA STATEMENT
C
	DATA T, TF, LEN, N, K, C, RHO, RATIO/0.0,20.,10.0,10,0.53,0.226,
          +		2.70, 0.25/
C
C  ------------------------------------------------------------------
C
C  READ IN THE INITIAL TEMPERATURES AND WRITE THEM OUT
C
	NP1 = N + 1
	DX = LEN / N
	DT = RATIO*C*RHO*DX*DX / K
	READ *, ( U(I), I = 1, NP1 )
	PRINT 201, T, LEN, DX, T, ( U(I), I = 1, NP1 )
C
C  ------------------------------------------------------------------
C
C  WE GET THE POTENTIAL FROM THE EXPLICIT RELATION, PRINTING EACH
C  SET OF VALUES AS THEY ARE COMPUTED.  TWO ARRARYS ARE USED,
C  HOLDING ALTERNATE SETS OF VALUES.
C
          10	THALF = T + CT/2.0
	U(1) = FLFT(THALF)
	U(N+1) = FRT(THALF)
	DO 20 I = 2, N
		V(I) - RATIO * ( U(I+1) + U (I-1)) + (1.0 - 2.0*RATIO ) * U(I)
          20	CONTINUE
	T = T + DT
	V(1) = FLFT(T)
	V(NP1) = FRT(T)
	PRINT 202, T, ( V(I), I = 1, NP1 )
	IF ( T .GT. TF ) STOP
C
C  ------------------------------------------------------------------
C
C  NOW DO SECOND SET OF VALUES
C
	THALF = T + DT/2.0
	V(1) = FLFT(THALF)
	V(N+1) = FRT(THALF)
	DO 30 I = 2, N
		U(I) = RATIO * ( V(I+1) + V(I-1)) + ( 1.0 - 2.0*RATIO )*V(I)
          30	CONTINUE
	T = T + DT
	U(1) = FLFT(T)
	U (NP1) = FRT(T)
	PRINT 202, T, ( U(I), I = 1, NP1 )
	IF ( T .GT. TF ) STOP
	GO TO 10
C
C  ------------------------------------------------------------------
C
         201	FORMAT(/' POTENTIAL VALUES IN ONE DIMENSION BY ',
          +		'EXPLICIT METHOD '/1X,' FOR X = ',F4.1,' TO X = ',
          +		F4.1,' WITH DELTA X OF ',F6.3//1X,' AT T = ',F6.3,
          +		/(1X,6F9.3) )
         202	FORMAT(/1X,' VALUES AT T = ',F8.3/(1X,6F9.3) )
	END
C
C  ------------------------------------------------------------------
C
C		FUNCTIONS DEFINED FOR THE LEFT AND
C		RIGHT HAND BOUNDARIES.
C
C  ------------------------------------------------------------------
C
	READ FUNCTION FLFT(X)
	REAL X
	FLFT = 0.0
	RETURN
	END
C
	REAL FUNCTION FRT(X)
	REAL X
	FRT = 100.0
	RETURN
	END

================================================================

I also have how the output of the program should look like:

================================================================

		OUTPUT FOR PROGRAM 1

POTENTIAL VALUES IN ONE DIMENSION BY EXPLICIT METHOD
  FOR X = 0.0 TO X = 10.0 WITH DELTA X OF 1.000

AT T = 0.000
  20.000	20.000	20.000	20.000	20.000	20.000
  20.000	20.000	20.000	20.000	20.000

VALUES AT T =	.288
  0.000	15.000	20.000	20.000	20.000	20.000
  20.000	20.000	20.000	40.000	100.000

VALUES AT T =	.576
  0.000	12.500	18.750	20.000	20.000	20.000
  20.000	20.000	25.000	50.000	100.000

VALUES AT T =	.863
  0.000	10.938	17.500	19.688	20.000	20.000
  20.000	21.250	30.000	56.250	100.000

VALUES AT T =	1.151
  0.000	9.844	16.406	19.219	19.922	20.000
  20.000	23.125	34.375	60.625	100.000

VALUES AT T =	1.439
  0.000	9.023	15.406	18.691	19.766	20.059
  20.938	25.234	38.125	63.906	100.00

		***** OUTPUT CONTINUED *****

VALUES AT T =	18.997
  0.000	7.742	15.699	24.065	33.002	42.616
  52.954	63.988	75.621	87.694	100.00

VALUES AT T =	19.285
  0.000	7.796	15.801	24.208	33.171	42.797
  53.128	64.138	75.731	87.752	100.00

VALUES AT T =	19.572
  0.000	7.848	15.902	24.347	33.337	42.973
  53.298	64.284	75.838	87.809	100.000

VALUES AT T =	19.860
  0.000	7.900	16.000	24.483	33.499	43.145
  53.463	64.426	75.942	87.864	100.000

VALUES AT T =	20.148
  0.000	7.950	16.096	24.616	33.656	43.313
  53.624	64.564	76.043	87.918	100.000

================================================================

I have gone through some online tutorials on FORTRAN, but I am still
having some difficulties understanding this code in entirety.  The
part I am confuse on is the "Read *, ( U(I), I = 1, NP1 )" part in the
program.  As I was browsing through the FORTRAN syntax online, I found
that "Read" has features such that it can initialize arrays, like
assign one value to the whole array dimension.  If my assumption is
right, then it seems the array U (from index 1 to NP1) is altered by
the Read statement.  It shows that at T = 0, all outputs are at
20.000, which is array U if I am reading the code right.  Also, it
seems the two defined functions do nothing more then just returning a
value, 0.0 and 100.0; if so, why take in a parameter (x)?  Well,
that's my concern in coding this in Java.

Thanks
Answer  
Subject: Re: FORTRAN program conversion and syntax inquiry
Answered By: eiffel-ga on 14 May 2003 04:09 PDT
Rated:5 out of 5 stars
 
Hi oogle,

It looks like your book is using a fairly old version of FORTRAN,
perhaps from the 1970's.

In those days, I/O facilities were relatively primitive and
non-standard, and it was common practice to hard-code runtime
parameters as statements in the program. To use different parameters,
one or a few of the punched cards from the program deck would be
"swapped out" prior to the program being compiled and run.

In your program, many of the parameters are initialized by the
following DATA statement:

C WE DEFINE SOME CONSTANTS WITH A DATA STATEMENT 
C 
 DATA T, TF, LEN, N, K, C, RHO, RATIO/0.0,20.,10.0,10,0.53,0.226,
          +  2.70, 0.25/

The lines starting with "C" are comments, and the line starting with
"+" is a continuation line is considered by the compiler to be part of
the previous statement. The result of the DATA statement is to
initialize the following variables:

  T = 0.0  /* starting time */
  TF = 20.0  /* final time for which values are computed */
  LEN = 10.0  /* length */
  N = 10  /* number of X intervals */
  K = 0.53  /* conductivity */
  C = 0.226  /* heat capacity */
  RHO = 2.70  /* density */
  RATIO = 0.25  /* ratio of (K (DT)) / (C * (RHO) * ((DX) ^ 2)) */

This takes care of all of the listed parameters except DX (which is
calculated as LEN/N), FLFT and FRT (which I will discuss later), and
the initial potentials along the length of the object that is the
subject of the potential flow analysis. These are read into an array
by the following statement:

 READ *, ( U(I), I = 1, NP1 )

The asterisk ("*") means to read from the standard input, which may
have been a terminal but more likely would have been one or more
punched cards loaded after the end of the program text. The remainder
of the statement is an implied DO loop, which is simply a shorthand
for listing the array elements from U(1) to U(NP1). Since N has been
set to 10, and NP1 has been set to N+1, the READ statement is simply
shorthand for this longer one:

 READ *, U(1), U(2), U(3), U(4), U(5), U(6), U(7), U(8), U(9), U(10),
U(11)

(Although it is possible for a READ statement to initialize an array
as a whole in later versions of FORTRAN such as FORTRAN 90, this is
not what your program is doing.)

Don't be misled by the fact that U is dimensioned in the program text
to have 500 elements. Early FORTRAN required that ARRAY dimensions
were fixed at compile time, and 500 would have been hard-coded as an
assumed maximum upper limit. In any given run, only the first NP1 of
these 500 array elements are used.

To produce the sample output data that you have listed, it would have
been necessary for the operator to provide input data such as the
following, to set a uniform starting potential of 20 at every point
along the length of the object:

20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0

The boundary conditions on the left and right end of the object under
study are given by the functions FLFT(X) and FRT(X). You are correct
in observing that in this program they simply return constants
unrelated to X. However they are provided as "boilerplate" functions
so that you can specify time-varying boundary conditions. In the old
FORTRAN days, the punched cards containing the statements computing
the return value of the functions (i.e. "FLFT = 0.0" and "FRT = 0.0")
could have been easily substituted with cards containing alternative
boundary functions.

I hope that this answer fills in the missing links in your
understanding of the FORTRAN version, and will help you to code your
Java version. If you'd like help with any other aspect of the FORTRAN
version, feel free to use the "Request Answer Clarification" feature.


Google search strategy:

fortran "read statement"
://www.google.com/search?q=fortran+%22read+statement%22

fortran read array
://www.google.com/search?q=fortran+read+array

fortran "implied do loop"
://www.google.com/search?q=fortran+%22implied+do+loop%22


Regards,
eiffel-ga
oogle-ga rated this answer:5 out of 5 stars and gave an additional tip of: $1.50
Hi eiffel-ga,

Thanks for your reply, it has helped me bringing my code up and
running.  I just turned the "Read *" statement into a readline()
method in Java using the BufferReader object, so taking in user
inputs, as you will see from the source code below.  Thanks again
eiffel-ga.

import java.lang.*;
import java.text.*;
import java.io.*;

public class explpa
{
   public static void main (String[] args) throws IOException
   {
      double U[] = new double [500];
      double V[] = new double [500];
      double dT, dx, THALF;
      int NP1, I, stdio;
      double T = 0.0;

      final double Tf = 20.0;
      final double Len = 10.0;
      final int N = 10;
      final double K = 0.53;
      final double C = 0.226;
      final double Rho = 2.70;
      final double Ratio = 0.25;
      
      NumberFormat dfmt = NumberFormat.getNumberInstance ();
      dfmt.setMaximumFractionDigits(3);
      dfmt.setMinimumFractionDigits(3);
      dfmt.setGroupingUsed(false);
      InputStreamReader isr = new InputStreamReader (System.in);
      BufferedReader br = new BufferedReader (isr);

      stdio = Integer.parseInt (br.readLine());
      NP1 = N +1;
      dx = Len / N;
      dT = ( Ratio * C * Rho * dx * dx ) / K;
      for (I = 1; I <= NP1; I++)
              U[I] = stdio;
      Output1(T,Len,dx,T,U, NP1);
      
      do
      {
        THALF = T + dT / 2.0;
        U[1] = Left();
        U[N + 1] = Right();
        for (I = 2; I <= N; I++)
        {
           V[I] = Ratio * (U[I + 1] + U[I - 1]) + (1.0 - 2 * Ratio) *
U[I];
        }
        T = T + dT;
        V[1] = Left();
        V[NP1] = Right();
        Output2(T, V, NP1);

        if (T > Tf) break;	//not a very good programming technique,
but will do for now

        THALF = T + dT / 2.0;
        V[1] = Left();
        V[N + 1] = Right();
      
        for (I = 2; I <= N; I++)
        {
           U[I] = Ratio * (V[I + 1] + V[I - 1]) + (1.0 - 2 * Ratio) *
V[I];
        }

        T = T + dT;
        U[1] = Left();
        U[NP1] = Right();
        Output2(T, U, NP1);

        if (T > Tf) break;	//not a very good programming technique,
but will do for now

      }
      while (true);	//not a very good programming technique, but will
do for now

   }

   static void Output1 (double x_from, double x_to, double delta_x,
double at_T, double U[], int NP1)
   {
      NumberFormat dfmt = NumberFormat.getNumberInstance();

      dfmt.setMaximumFractionDigits(3);
      dfmt.setMinimumFractionDigits(3);
      dfmt.setGroupingUsed(false);

      StringBuffer OutputMessage = new StringBuffer();
         OutputMessage.append("Potential values in one dimension by
explicit method\n");
         OutputMessage.append ("   For X =   ");
         OutputMessage.append ( x_from );
         OutputMessage.append (" to X =   ");
         OutputMessage.append ( x_to );
         OutputMessage.append (" with delta X of   ");
         OutputMessage.append ( delta_x );
         OutputMessage.append ("\n\n");
         OutputMessage.append ("At T =  ");
         OutputMessage.append ( dfmt.format(at_T) );

      System.out.println(OutputMessage.toString());

      int k=0;

      for (int i = 1; i <= NP1; i++)
      {
         System.out.print("  " + dfmt.format(U[i]));

         k++;

         if (k==6) System.out.println();
      }

      System.out.println();
      System.out.println();

   }

   static void Output2 (double T, double V[], int NP1)
   {
      NumberFormat dfmt = NumberFormat.getNumberInstance();
      dfmt.setMaximumFractionDigits(3);
      dfmt.setMinimumFractionDigits(3);
      dfmt.setGroupingUsed(false);
      
      System.out.print("Values at T = " + dfmt.format(T) + "\n");

      int k=0;

      for (int i = 1; i <= NP1; i++)
      {
         System.out.print("  " + dfmt.format(V[i]) );

         k++;

         if (k==6) System.out.println();
      }

      System.out.println();
      System.out.println();

   }

   static double Left ()
   {
      return 0.0;
   }

   static double Right ()
   {
      return 100.0;
   }

}

Comments  
Subject: Re: FORTRAN program conversion and syntax inquiry
From: eiffel-ga on 15 May 2003 23:45 PDT
 
Thanks for posting the Java version - it was interesting to compare it
with the FORTRAN version. Thanks, too, for the kind tip.

-- eiffel-ga

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy