1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Fortran help

  1. Mar 12, 2012 #1
    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: '
    READ(*,*) 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 (%): '
    READ(*,*) c_0
    WRITE(*,'(A,\)') 'Enter diffusion parameter (m^3/sec): '
    READ(*,*) d_0
    WRITE(*,'(A,\)') 'Enter activation energy (J): '
    READ(*,*) q
    WRITE(*,'(A,\)') 'Enter temperature (K): '
    READ(*,*) temp
    WRITE(*,'(A,\)') 'Enter length of bar (m): '
    READ(*,*) l
    WRITE(*,'(A,\)') 'Enter desired average final concentration (%): '
    READ(*,*) c_r
    WRITE(*,*) ''
    WRITE(*,*) ' The bisection method needs an initial search interval [A,B].'
    WRITE(*,*) ''
    DO
    WRITE(*,'(A,\)') 'Enter a A (Years):'
    READ(*,*) a
    WRITE(*,'(A,\)') 'Enter a B (Years):'
    READ(*,*) b
    IF(a < b) THEN
    EXIT
    ELSE
    WRITE(*,*) 'Error- left end point needs to be smaller than right end point.'
    WRITE(*,*) 'Please enter again:'
    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
     
  2. jcsd
  3. Mar 12, 2012 #2
    Can someone just error check this and explain whats wrong the compiler just tells me random errors which I dont know
     
  4. Mar 13, 2012 #3

    Mark44

    Staff: Mentor

    Tell us what the errors are - they are probably not "random."
     
  5. Mar 13, 2012 #4
    Hmm alriight it says that C_avg has no implicit type
     
  6. Mar 13, 2012 #5
    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.
     
  7. Mar 13, 2012 #6
    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?
     
  8. Mar 13, 2012 #7
    How exactly are you supposed to do the functions because thats what causing me the problems
     
  9. Mar 13, 2012 #8
    oh for your computation problem was this the issue
    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.
     
  10. Mar 13, 2012 #9

    Mark44

    Staff: Mentor

    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 (Text):

    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 (Text):

    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 (Text):

    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.
     
  11. Mar 13, 2012 #10
    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?
     
  12. Mar 13, 2012 #11
    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: '
    READ(*,*) 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 (%): '
    READ(*,*) c_0
    WRITE(*,'(A,\)') 'Enter diffusion parameter (m^3/sec): '
    READ(*,*) d_0
    WRITE(*,'(A,\)') 'Enter activation energy (J): '
    READ(*,*) q
    WRITE(*,'(A,\)') 'Enter temperature (K): '
    READ(*,*) temp
    WRITE(*,'(A,\)') 'Enter length of bar (m): '
    READ(*,*) l
    WRITE(*,'(A,\)') 'Enter desired average final concentration (%): '
    READ(*,*) c_r
    WRITE(*,*) ''
    WRITE(*,*) ' The bisection method needs an initial search interval [A,B].'
    WRITE(*,*) ''
    DO
    WRITE(*,'(A,\)') 'Enter a A (Years):'
    READ(*,*) a
    WRITE(*,'(A,\)') 'Enter a B (Years):'
    READ(*,*) b
    IF(a < b) THEN
    EXIT
    ELSE
    WRITE(*,*) 'Error- left end point needs to be smaller than right end point.'
    WRITE(*,*) 'Please enter again:'
    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: Mar 13, 2012
  13. Mar 13, 2012 #12
    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.
     
  14. Mar 13, 2012 #13
    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
     
  15. Mar 14, 2012 #14

    Mark44

    Staff: Mentor

    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.
     
  16. Mar 14, 2012 #15

    Mark44

    Staff: Mentor

    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.
     
  17. Mar 16, 2012 #16
    Did anyone find a solution to this? my project has the same error.
     
  18. Mar 16, 2012 #17

    Mark44

    Staff: Mentor

    Did you try what I suggested a couple of posts ago?
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Fortran help
  1. Help with fortran (Replies: 1)

  2. Fortran Help! (Replies: 4)

Loading...