Fortran Having some issues with a piece of fortran95 code

AI Thread Summary
The discussion revolves around troubleshooting issues in a Fortran 95 program. The user initially encounters compilation errors due to variable naming conflicts and incorrect output statements. Solutions provided include declaring arrays properly and using the WRITE statement correctly to output values to files. The user also learns that integer division can lead to unexpected results, and converting integers to real numbers can resolve calculation issues. Finally, the user seeks advice on reversing the output order for lower surface results, considering the use of arrays to store values for later retrieval and printing.
charlie87
Messages
8
Reaction score
0
Hello,

I am pretty new to programming at all and am having some issues with working out why this program is not compiling:


Program MAIN
DO J = 1, 11
K = 10 + J
P = 0.4 !POSITION OF MAXIMUM CAMBER AT 40% CHORD!
M = FLOAT (J + 1)* 0.01 !MAXIMUM CAMBER!
DO I = 1, 11
DO X = 0, 1
DX = 1
IF (X .LT. P) THEN
Yc = (M/(P*P))*(2*P*X-(X*X))
ELSE
Yc = (M/((1-P)*(1-P))*((1-(2*P))+(2*P*X)-(X*X)))
END IF
DYc = Yc(I) - (Yc(I - 1))
FIRST = 0.2969*SQRT(X)
SECOND = 0.1260*X
THIRD = 0.3516*X*X
FOURTH = 0.2843*X*X*X
FIFTH = 0.1015*X*X*X*X
Yt = (T/0.2)*(FIRST - SECOND - THIRD + FOURTH - FIFTH)
THETA = ATAN(DYc/DX)
Yupper = Yc + (Yt*COS(THETA))
Ylower = Yc - (Yt*COS(THETA))
END DO
END DO
WRITE (J, *)
DO I = 1, 11
X(I), Yupper(I), Ylower(I)
END DO
END DO


The code in bold red font are the problem lines and the compiler gives me an "Unclassifiable statement" error for both lines.

Any help would be very much appreciated.

Regards,
Charlie
 
Technology news on Phys.org
Code:
DYc = Yc(I) - (Yc(I - 1))

If you want to use an array in Fortan you have to declare it first, for example

Code:
Program MAIN
DIMENSION Yc(11)
DO J = 1,11
etc

But you have already used Yc as a scalar variable. You can't use the same variable name for two different things.

Code:
X(I), Yupper(I), Ylower(I)

I can't even guess what type of Fortran statement that was supposed to be. Neither can the compiler, hence the error message.
 
Thanks very much for the prompt reply,

The DYc variable i was trying to get was just a delta value of Yc so I thought the I-(I-1) statement mathematically correct.

Also the code:
X(I), Yupper(I), Ylower(I)
I wanted the program to write all three variables to the file fort.(I)

sorry again first time coding so have been patching together all the resources I could find.

Regards,
Charles
 
charlie87 said:
Thanks very much for the prompt reply,

The DYc variable i was trying to get was just a delta value of Yc so I thought the I-(I-1) statement mathematically correct.

Also the code:
X(I), Yupper(I), Ylower(I)
I wanted the program to write all three variables to the file fort.(I)
Then you need to use an output function - WRITE.

Are you trying to write different values to different files? If you don't know that you need to use an output function to do output, you're going to have a really tough time doing output to separate files.

It would behoove you to do some research on Fortran file I/O.


charlie87 said:
sorry again first time coding so have been patching together all the resources I could find.

Regards,
Charles
 
I am trying to write all three variables to one file. then repeat the process 'I' times

I used the write command as shown:

WRITE (J, *)
DO I = 1, 11
X(I), Yupper(I), Ylower(I)

So i would have assumed that the code would write to the file fort.(J) the X, Yupper and Ylower values for each 'I' value.

What I am hoping to receive is a number of files of the following format:

I X Yupper Ylower
--------------------------------
1 | | |
2 | | |
3 | | |
4 | | |
 
charlie87 said:
I used the write command as shown:

WRITE (J, *)
DO I = 1, 11
X(I), Yupper(I), Ylower(I)

So i would have assumed that the code would write to the file fort.(J) the X, Yupper and Ylower values for each 'I' value.

Unfortunately, "assuming" the compiler will guess what your program is supposed to do usually fails. :rolleyes:

In Fortran each WRITE statement produces one line of output. So you need something like
Code:
DO I = 1, 11
WRITE (J, *) X(I), Yupper(I), Ylower(I)
ENDDO

Actually, that won't quite work either, because in your outer loop j goes from 1 to 11, but Fortran reserves a few file numbers for "default" files which read input from the keyboard and write output to the monitor. Those numbers may be 0 1 and 2, or sometimes 5 and 6 (for historical reasons). If you want to create 11 files on disk, the simplest fix for this would be to use file numbers like 11 thru 21 or 51 thru 61 or whatever, which won't clash with anything else.
 
Thanks for all the responses so far. Right I have reworked my intial code now and have got it to work and compile however I still do have a problem in that one of my calculations is not being carried out.

Code:

DO J = 1, 11
NP = 11 !NUMBER OF POINTS ALONG CHORD!
K = 10 + J !CHANNEL TO WRITE TO!
P = 0.4 !POSITION OF MAXIMUM CAMBER AT 40% CHORD!
P2 = P*P !P SQUARED!
T = 0.12 !WING THICKNESS!
PI = 3.1415927
XR = (PI/(NP-1)) !GET RADIAN DISTRIBUTION!
Yc1 = 0 !VARIABLE TO CALULATE DELTA Yc!
NACA = (J*1000)+(P*1000)+(T*100)
WRITE (K,*) 'NACA', NACA
WRITE (K, '(1X,I10, "X", I14,"Y")') 1, 1
DO XT = 1, NP !REPEAT LOOP FOR AS MANY POINTS REQUIRED!
XC = (XR*(XT - 1)) !GET EQUAL SPACING IN RADIANS!
X = ((COS(XC)) + 1) / 2 !HALF COSINE DISTRIBUTION!
X2 = X*X
X3 = X*X*X
X4 = X*X*X*X
IF (X .LT. P) THEN !DECIDE WHICH EQUATION TO USE!
Yc = ((J/100)/P2)*(2*P*X-(X2))
ELSE
Yc = ((J/100)/(1-(2*P)+P2))*((1-(2*P))+(2*P*X)-(X2))
END IF
WRITE (6, *) Yc
FIRST = 0.2969*SQRT(X) !Yt EQUATION BROKEN DOWN!
SECOND = 0.1260*X !Yt EQUATION BROKEN DOWN!
THIRD = 0.3516*X2 !Yt EQUATION BROKEN DOWN!
FOURTH = 0.2843*X3 !Yt EQUATION BROKEN DOWN!
FIFTH = 0.1015*X4 !Yt EQUATION BROKEN DOWN!
Yt = (T/0.2)*(FIRST - SECOND - THIRD + FOURTH - FIFTH)
DYc = (Yc1 - Yc)
DX = 1
THETA = ATAN(DYc/DX)
Yupper = Yc + (Yt*COS(THETA))
Ylower = Yc - (Yt*COS(THETA))
Yc1 = Yc
WRITE (K, *) X, Yupper, Yc
END DO
DO XT = (NP-1), 1, -1 !REPEAT LOOP FOR AS MANY POINTS REQUIRED!
XC = (XR*(XT - 1)) !GET EQUAL SPACING IN RADIANS!
X = ((COS(XC)) + 1) / 2 !HALF COSINE DISTRIBUTION!
X2 = X*X
X3 = X*X*X
X4 = X*X*X*X
IF (X .LT. P) THEN
Yc = ((J/100)/P2)*(2*P*X-(X2))
ELSE
Yc = ((J/100)/(1-(2*P)+P2))*((1-(2*P))+(2*P*X)-(X2))
END IF
WRITE (6, *) Yc
FIRST = 0.2969*SQRT(X) !Yt EQUATION BROKEN DOWN!
SECOND = 0.1260*X !Yt EQUATION BROKEN DOWN!
THIRD = 0.3516*X2 !Yt EQUATION BROKEN DOWN!
FOURTH = 0.2843*X3 !Yt EQUATION BROKEN DOWN!
FIFTH = 0.1015*X4 !Yt EQUATION BROKEN DOWN!
Yt = (T/0.2)*(FIRST - SECOND - THIRD + FOURTH - FIFTH)
DYc = (Yc1 - Yc)
DX = 1
THETA = ATAN(DYc/DX)
Yupper = Yc + (Yt*COS(THETA))
Ylower = Yc - (Yt*COS(THETA))
Yc1 = Yc
WRITE (K, *) X, Ylower, Yc
END DO
END DO
END PROGRAM



The Yc variables are always set to zero and I can't figure out why. All the components are ok and so the calculations should be ok. any help would be greatly appreciated.

Regards,
Charles
 
Yc = ((J/100)/P2)*(2*P*X-(X2))

Variables with names starting with the letters I thru N are integer variables.

J/100 is dividing an integer by an integer, and Fortran gives the result of that as an integer. J/100 will always equal = 0 if J is less than 100. You can fix this with

Yc = ((J/100.0)/P2)*(2*P*X-(X2))

Dividing an integer by a real constant (written with a decimal point) will give a real result, which seems to be what you want.

Or you could write

Yc = ((J/(100*P2))*(2*P*X-(X2))

100*P2 is an integer times a real which gives a real value. Then J / (real value) gives another real value.
 
AlephZero,

Thank you very much that is absolutely perfect. I thought it would be a simple solution but just could not see it myself.

Thank you again for all of your help.
 
  • #10
I have another hopefully simple to answer problem. In my code I have got it to calculate x values from 0 - 1 in decimal values and the y values associated with these. I than print off the values straight away and progress the x value so i end up with a table like so:


NACA 2412
X Y Z
upper surface
1.0000000 0.0000000 0.0000000
0.97552824 0.0000000 5.01149474E-03
0.90450847 0.0000000 1.86340362E-02
0.79389262 0.0000000 3.72849256E-02
0.65450847 0.0000000 5.64936101E-02
0.49999997 0.0000000 7.17544481E-02
0.34549147 0.0000000 7.87679926E-02
0.20610739 0.0000000 7.27545992E-02
9.54914838E-02 0.0000000 5.43368347E-02
2.44717114E-02 0.0000000 2.82343049E-02
1.91068949E-15 0.0000000 7.78673392E-09
lower surface
1.0000000 0.0000000 0.0000000
0.97552824 0.0000000 -1.81513163E-03
0.90450847 0.0000000 -6.91501191E-03
0.79389262 0.0000000 -1.45239700E-02
0.65450847 0.0000000 -2.36907862E-02
0.49999997 0.0000000 -3.28655615E-02
0.34549147 0.0000000 -3.95107903E-02
0.20610739 0.0000000 -4.21531908E-02
9.54914838E-02 0.0000000 -3.75181958E-02
2.44717114E-02 0.0000000 -2.34896801E-02

is there a way that I can get the lower surface results to be displayed in reverse order (from 0 to 1) the code will not allow me just do

do 11, 1, -1

as the equations used do not have the sufficient variables in this direction.
should I save the x and y values to an array and then get the array to be read and printed backwards? if so how do i do this.

I have attached my revised code.
 

Attachments

Similar threads

Replies
8
Views
4K
Replies
5
Views
2K
Replies
8
Views
2K
Replies
12
Views
3K
Replies
8
Views
2K
Back
Top