# Fortran help

• Comp Sci
MODULE space_data
REAL :: l !LENGTH OF THE BAR
REAL :: temp !TEMPERATURE IN KELVIN
REAL :: d_0 !CONSTANT DIFFUSION PARAMETER
REAL :: q !ACTIVATION ENERGY
REAL :: c_0 !INITIAL CONCENTRATION AT X=0
REAL :: r=8.31 !IDEAL GAS CONSTANT IN J/molK
REAL :: c_r !DESIRED END CONCENTRATION
INTEGER :: imax=30 !MAXIMUM ITERATIONS
REAL :: eps=1E-4 !MAXIUMUM ERROR
REAL :: a, b !INTERVAL OF EVALUATION [A,B]
REAL :: t
REAL :: exp, df !, erf, c, c_avg
END MODULE space_data

PROGRAM carburization
USE space_data
IMPLICIT NONE
CHARACTER :: choice
REAL :: f, root
INTEGER :: ercode

DO
WRITE(*,*) 'a) Enter new data'
WRITE(*,*) 'b) Calculate time until desired concentration'
WRITE(*,*) 'q) Quit'
WRITE(*,'(A,\)') 'Enter choice: '
SELECT CASE(choice)
CASE('A','a')
CALL call_data()
CASE('B','b')
CALL bisection(f, root, ercode)
CALL results()
CASE('Q','q')
STOP
END SELECT
END DO

CONTAINS

SUBROUTINE call_data()
USE space_data
IMPLICIT NONE
WRITE(*,'(A,\)') 'Enter initial end concentration (%): '
WRITE(*,'(A,\)') 'Enter diffusion parameter (m^3/sec): '
WRITE(*,'(A,\)') 'Enter activation energy (J): '
WRITE(*,'(A,\)') 'Enter temperature (K): '
WRITE(*,'(A,\)') 'Enter length of bar (m): '
WRITE(*,'(A,\)') 'Enter desired average final concentration (%): '
WRITE(*,*) ''
WRITE(*,*) ' The bisection method needs an initial search interval [A,B].'
WRITE(*,*) ''
DO
WRITE(*,'(A,\)') 'Enter a A (Years):'
WRITE(*,'(A,\)') 'Enter a B (Years):'
IF(a < b) THEN
EXIT
ELSE
WRITE(*,*) 'Error- left end point needs to be smaller than right end point.'
END IF
END DO
END SUBROUTINE call_data

END PROGRAM carburization

SUBROUTINE bisection(f, root, ercode)
USE space_data
IMPLICIT NONE
INTEGER::I
REAL,EXTERNAL::F
REAL,INTENT(OUT)::ROOT !THE ROOT WE ARE TRYING TO FIND
REAL::X1,X2,X3,F1,F2,F3,D,D01 !X VALUES, F(X) VALUES AND INTERVAL LENGTHS
INTEGER,INTENT(OUT)::ERCODE !ERROR CODE WILL RETURN AN INT VALUE BASED ON OUTCOME
!-1 MEANS ITERATION CNT EXCEED
!-2 MEANS NO ROOT IN INTERVAL A-B
!-3 UNKNOWN ERROR
! 0 ROOT FOUND, BISECTION METHOD SUCCESSFUL
X1=A
X3=B
F1 = F(X1)
F3 = F(X3)
IF(F1*F3>0) THEN
ERCODE = -2 !-2 MEANS NO ROOT IN INTERVAL A-B
ELSE
D=1
I=0
D01=A-B
DO
X2 = (X1+X3)/2.
F2 = F(X2)
IF(D<EPS) THEN
ROOT = X2
ERCODE = 0 !SUCCESS
EXIT
ELSE IF(I>IMAX) THEN
ERCODE = -1 !-1 MEANS ITERATION CNT EXCEED
EXIT
END IF
IF(F1*F2<0) THEN !LEFT
D = (X2-X1)/D01
F3 = F2
X3 = X2
ELSE IF(F2*F3<0)THEN!RIGHT
D = (X3-X2)/D01
F1 = F2
X1 = X2
ELSE IF(F2 == 0) THEN
ROOT = X2
ERCODE = 0 !SUCCESS
EXIT
ELSE
ERCODE = -3 !-3 UNKNOWN ERROR
EXIT
END IF
I = I+1
END DO
END IF
END SUBROUTINE

SUBROUTINE results()
USE space_data
IMPLICIT NONE
WRITE(*, '(T5,A)') 'RESULTS:'
WRITE(*, '(T5, 50("-"))')
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.3, 1X, "|")') 'Initial end concentration (%)',c_0
WRITE(*,'(T5, "|", 1X, A,T40, "|", ES12.3, 1X, "|")') 'Diffusion parameter (m^3/sec):',d_0
WRITE(*,'(T5, "|", 1X, A,T40, "|", ES12.3, 1X, "|")') 'Activationenergy (J):',q
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.2, 1X, "|")') 'Temperature (K):',temp
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.2, 1X, "|")') 'Length of bar (m):',l
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.3, 1X, "|")') 'Final concentration (%):',c_r
WRITE(*, '(T5, 50("-"))')
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.3, 1X, "|")') 'Computed diffusion time (days):',t
WRITE(*, '(T5, 50("-"))')
WRITE(*,*)
END SUBROUTINE results

REAL FUNCTION f()
USE space_data
IMPLICIT NONE
f = c_avg - c_r
END FUNCTION f

REAL FUNCTION c ()
USE space_data
IMPLICIT NONE
REAL :: z, x

df = d_0*(exp**(-q/(r*temp)))

x=l
z = x/(2*df*t)
c = (c_0/2.)*(1 - ERF(z))
END FUNCTION c

REAL FUNCTION c_avg ()
USE space_data
IMPLICIT NONE
REAL :: delta_x, idx
INTEGER :: i
delta_x = .2
DO i = 0, 5
idx = i*delta_x
c_avg = c_avg + (1/6.)*( c(idx,t) )
END DO
END FUNCTION c_avg

Related Engineering and Comp Sci Homework Help News on Phys.org
Can someone just error check this and explain whats wrong the compiler just tells me random errors which I dont know

Mark44
Mentor
Tell us what the errors are - they are probably not "random."

Hmm alriight it says that C_avg has no implicit type

Hey I think you're in my class. c_avg is a function but you defined it as just a REAL in the module. I didn't define any functions in the module because I kept getting errors. You also have to have input variables for your function's dummy variables. So c_avg would just be a function of time because we only have to calculate the concentration at the end of the bar (x = Length of bar). I don't have any compiler errors but I keep getting the wrong answer so I just have something wrong with the calculation.

REAL FUNCTION c_avg (t)
USE space_data
IMPLICIT NONE
REAL, INTENT(IN):: t
REAL :: delta_x, idx
INTEGER :: i
delta_x = .2
DO i = 0, 5
idx = i*delta_x
c_avg = c_avg + (1/6.)*( c(idx,t) )
END DO
END FUNCTION c_avg

EDIT

I just saw this in the module REAL :: exp, df !, erf, c, c_avg
It might not be reading what's after the exclamation point because it counts it as a comment.

K put in the t function stuff but I am still getting errors, how did you define your function within the main program? also what do you mean imput variables for dummy variables?

How exactly are you supposed to do the functions because thats what causing me the problems

The initial search interval [A,B] is given in years. The calculations require you to convert these
two into seconds.
 Likewise, the answer you get will be in seconds. You have to convert it back to years before you
print it out.

Mark44
Mentor
Hmm alriight it says that C_avg has no implicit type
In your f function, you have two undeclared variables, c_avg and c_r. Did you intend to call your c_avg function inside f? If so, you have another problem - you are not calling c_avg correctly. When you call a function, you need to include parentheses after the function name.

I'm not sure what c_r is. If it's another function, I didn't find it, but I didn't look that carefully at your code. If c_r is a function, you aren't calling it correctly, either.
Code:
REAL FUNCTION f()
USE space_data
IMPLICIT NONE
f = c_avg - c_r
END FUNCTION f

I see problems in this code as well - t is undeclared. When you use IMPLICIT NONE, you HAVE TO declare all variables.

The other problem is that you are calling your c function and passing two arguments to it, but the definition of this function shows that it has no parameters.
Code:
REAL FUNCTION c_avg ()
USE space_data
IMPLICIT NONE
REAL :: delta_x, idx
INTEGER :: i
delta_x = .2
DO i = 0, 5
idx = i*delta_x
c_avg = c_avg + (1/6.)*( c(idx,t) )
END DO
END FUNCTION c_avg
Code:
REAL FUNCTION c ()
USE space_data
IMPLICIT NONE
REAL :: z, x

df = d_0*(exp**(-q/(r*temp)))

x=l
z = x/(2*df*t)
c = (c_0/2.)*(1 - ERF(z))
END FUNCTION c
BTW, using single letter names for functions (e.g., f and c) is not good programming practice. Almost every variable or function name should give a clear indication about what it is used for. The only exceptions are loop control variables such as i, j, etc.

hmm so all I have to do in terms of putting a function within a function is to put the parenthesis afterwards but wont it thinks its an array or something?

MODULE space_data
REAL :: L !LENGTH OF THE BAR
REAL :: temp !TEMPERATURE IN KELVIN
REAL :: d_0 !CONSTANT DIFFUSION PARAMETER
REAL :: q !ACTIVATION ENERGY
REAL :: c_0 !INITIAL CONCENTRATION AT X=0
REAL :: r=8.31 !IDEAL GAS CONSTANT IN J/molK
REAL :: c_r !DESIRED END CONCENTRATION
INTEGER :: imax=30 !MAXIMUM ITERATIONS
REAL :: eps=1E-4 !MAXIUMUM ERROR
REAL :: a, b !INTERVAL OF EVALUATION [A,B]
END MODULE space_data

PROGRAM carburization
USE space_data
IMPLICIT NONE
CHARACTER :: choice
REAL :: f, root
INTEGER :: ercode

DO

WRITE(*,*) 'a) Enter new data'
WRITE(*,*) 'b) Calculate time until desired concentration'
WRITE(*,*) 'q) Quit'
WRITE(*,'(A,\)') 'Enter choice: '

SELECT CASE(choice)
CASE('A','a')
CALL call_data()

CASE('B','b')
CALL bisection(f, root, ercode)
CALL results()

CASE('Q','q')
STOP
END SELECT

END DO

CONTAINS

SUBROUTINE call_data()
USE space_data
IMPLICIT NONE
WRITE(*,'(A,\)') 'Enter initial end concentration (%): '
WRITE(*,'(A,\)') 'Enter diffusion parameter (m^3/sec): '
WRITE(*,'(A,\)') 'Enter activation energy (J): '
WRITE(*,'(A,\)') 'Enter temperature (K): '
WRITE(*,'(A,\)') 'Enter length of bar (m): '
WRITE(*,'(A,\)') 'Enter desired average final concentration (%): '
WRITE(*,*) ''
WRITE(*,*) ' The bisection method needs an initial search interval [A,B].'
WRITE(*,*) ''
DO
WRITE(*,'(A,\)') 'Enter a A (Years):'
WRITE(*,'(A,\)') 'Enter a B (Years):'
IF(a < b) THEN
EXIT
ELSE
WRITE(*,*) 'Error- left end point needs to be smaller than right end point.'
END IF
END DO
END SUBROUTINE call_data

END PROGRAM carburization

SUBROUTINE bisection(f, root, ercode)
USE space_data
IMPLICIT NONE
INTEGER::I
REAL,EXTERNAL::F
REAL,INTENT(OUT)::ROOT !THE ROOT WE ARE TRYING TO FIND
REAL::X1,X2,X3,F1,F2,F3,D,D01 !X VALUES, F(X) VALUES AND INTERVAL LENGTHS
INTEGER,INTENT(OUT)::ERCODE !ERROR CODE WILL RETURN AN INT VALUE BASED ON OUTCOME
!-1 MEANS ITERATION CNT EXCEED
!-2 MEANS NO ROOT IN INTERVAL A-B
!-3 UNKNOWN ERROR
! 0 ROOT FOUND, BISECTION METHOD SUCCESSFUL
X1=A
X3=B
F1 = F(X1)
F3 = F(X3)
IF(F1*F3>0) THEN
ERCODE = -2 !-2 MEANS NO ROOT IN INTERVAL A-B
ELSE
D=1
I=0
D01=A-B
DO
X2 = (X1+X3)/2.
F2 = F(X2)
IF(D<EPS) THEN
ROOT = X2
ERCODE = 0 !SUCCESS
EXIT
ELSE IF(I>IMAX) THEN
ERCODE = -1 !-1 MEANS ITERATION CNT EXCEED
EXIT
END IF
IF(F1*F2<0) THEN !LEFT
D = (X2-X1)/D01
F3 = F2
X3 = X2
ELSE IF(F2*F3<0)THEN!RIGHT
D = (X3-X2)/D01
F1 = F2
X1 = X2
ELSE IF(F2 == 0) THEN
ROOT = X2
ERCODE = 0 !SUCCESS
EXIT
ELSE
ERCODE = -3 !-3 UNKNOWN ERROR
EXIT
END IF
I = I+1
END DO
END IF
END SUBROUTINE

SUBROUTINE results()
USE space_data
IMPLICIT NONE
WRITE(*, '(T5,A)') 'RESULTS:'
WRITE(*, '(T5, 50("-"))')
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.3, 1X, "|")') 'Initial end concentration (%)',c_0
WRITE(*,'(T5, "|", 1X, A,T40, "|", ES12.3, 1X, "|")') 'Diffusion parameter (m^3/sec):',d_0
WRITE(*,'(T5, "|", 1X, A,T40, "|", ES12.3, 1X, "|")') 'Activationenergy (J):',q
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.2, 1X, "|")') 'Temperature (K):',temp
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.2, 1X, "|")') 'Length of bar (m):',L
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.3, 1X, "|")') 'Final concentration (%):',c_r
WRITE(*, '(T5, 50("-"))')
WRITE(*,'(T5, "|", 1X, A,T40, "|", F12.3, 1X, "|")') 'Computed diffusion time (days):'
WRITE(*, '(T5, 50("-"))')
WRITE(*,*)
END SUBROUTINE results

REAL FUNCTION Con()
USE Space_data
IMPLICIT NONE
REAL :: t,z,x,DF,delta_x,idx
INTEGER :: i
delta_x=L/5
t=(B-A)*31556926
DF=D_0*EXP(-q/(R*temp))
DO i = 0,5
idx=i*delta_x
z = idx/(2*DF*t)
con = (c_0/2.)*(1 - ERF(z))
END DO
END FUNCTION

REAL FUNCTION C_avg()
USE Space_data
IMPLICIT NONE
REAL,EXTERNAL :: Con
C_avg=(1/6)*Con()
END FUNCTION

REAL FUNCTION f()
USE Space_data
IMPLICIT NONE
REAL,EXTERNAL :: C_avg
f = C_avg()-C_r
END FUNCTION

Last edited:
The t (time) is either A or B which you have to ask for as the input (10 and 50 in the pdf). When the program runs, it will evaluate the function(s) for these two times, but they have to be in seconds. We only care about the end of the bar so X or delta X will always just be the length of the bar, then these are only functions of time.

I don't want to post my code here but if you go to the lab on Thursday I can show you how I did the functions.

Oh yeah, it says the time input is in years, but it's actually days, so when you convert A and B to seconds, make sure you convert from days to seconds, not years to seconds.

So my code compiles but now i get an error when I put in data and enter choice b
it says exception access violation
traceback not available

Mark44
Mentor
hmm so all I have to do in terms of putting a function within a function is to put the parenthesis afterwards but wont it thinks its an array or something?
Not if you have declared your variables (including arrays) and functions properly. From the declarations, the compiler can tell the difference between a function call and an array.

When you call a function there is more to it than just putting a pair of parentheses after the function name. The number of parameters in the function call has to agree with the number of parameters in the function definition. Also, the types of the parameters have to agree.

Mark44
Mentor
So my code compiles but now i get an error when I put in data and enter choice b
it says exception access violation
traceback not available
So now you need to do some debugging. Entering 'b' for the choice causes your program to call your bisection subroutine, and then the results routine. If you have a debugger available, it would be good to learn how to use it. If using a debugger is not an option, you can use the oldest debugging technique, which is to insert output statements in your code so that your program displays the values of variables. You should be able to predict what the values of variables will be by hand calculation.

I'm guessing that the exception you're seeing results from attempting to access an array using an index that's out of range.

Did anyone find a solution to this? my project has the same error.

Mark44
Mentor
Did you try what I suggested a couple of posts ago?
Did anyone find a solution to this? my project has the same error.
So now you need to do some debugging. Entering 'b' for the choice causes your program to call your bisection subroutine, and then the results routine. If you have a debugger available, it would be good to learn how to use it. If using a debugger is not an option, you can use the oldest debugging technique, which is to insert output statements in your code so that your program displays the values of variables. You should be able to predict what the values of variables will be by hand calculation.

I'm guessing that the exception you're seeing results from attempting to access an array using an index that's out of range.