Sooner than expected, I have yet another problem with my Fortran code. This time I'm trying to find the zeros of a function, which I can normally do, but now I have a function that has more than one input:
Where gamma, mp and k are just numbers; but u and mu are other values that I have to input for external arrays. In particular mu is another non-linear function of T, but I have an array of all mus for the temperatures I'm considering.
REAL*8 FUNCTION f(T, mu, u)
IMPLICIT NONE
REAL*8:: T, mu, u
REAL*8, PARAMETER:: mp = 1.67e-24, gammaa = 1.666666666d0, k_boltz = 1.380649e-16
f = T - ((gammaa - 1) * ((u * mu * mp) / k_boltz))
END FUNCTION f
The way I'm implementing the secant method is:
SUBROUTINE secant(f, x0, n_max, accuracy, mu, u, res)
IMPLICIT NONE
REAL*8, EXTERNAL:: f
REAL*8, INTENT(in):: accuracy
INTEGER, INTENT(in):: n_max
REAL*8, INTENT(inout):: x0
REAL*8, INTENT(out):: res(2)
REAL*8:: x_next, dx, derivate, mu, u
INTEGER:: counter
derivate = (f(x0+0.001d0, mu, u) - f(x0, mu, u)) / 0.001d0
counter = 0
DO
counter = counter + 1
IF (counter > n_max) THEN
PRINT*, "Too many iterations with no result."
STOP
END IF
x_next = x0-f(x0, mu, u)/derivate
dx = ABS(x_next - x0)
IF (dx<accuracy) THEN
res(1) = x_next
res(2) = f(x_next, mu, u)
STOP
END IF
x0 = x_next
END DO
END SUBROUTINE secante
Which is the same way I implement it for functions of single input functions, only with the extra inputs now hard coded in. I thought this would work fine, but for some reason after calling:
t0 = 1.d0 ! arbitrary starting point
DO i = 1, n
CALL secante(f, t0, 5, 0.00001d0, mu(i), int_energy(i), temperature(i))
ENDDO
I get a division by zero error in my terminal: "Note: The following floating-point exceptions are signalling: IEEE_DIVIDE_BY_ZERO"
I've tried changing all the values I can change on the fractions in the subroutine, but still no luck.
Any ideas?