# Fortran Programming for order differential equation

• Comp Sci
Consider the first order differential equation
dy/dy = f(t,y) = -16 t^3 y^2
with initial condition y(0)=1

Using second order Adams-Bashforth method, write a Fortran programming to generate an approximate solution to the problem.

please forgive me for not trying because I really don't how to do.
The only thing I know is exact solution :(4t^4 + 1)^-1 which I have done it by hand. Help me

Related Engineering and Comp Sci Homework Help News on Phys.org
SteamKing
Staff Emeritus
Homework Helper
We can't teach you how to program. It would be better for you to find someone at your school who knows programming who could work with you.

Implicit None
Real, allocatable :: y(:),t(:)
Real:: yo, tmax, h, k1,k2,y1
Integer:: NI, i
Real, external :: f

Print*, 'Enter yo,Tmax,NJ'
h= Tmax/NI
Print*, 'This gives stepsize h=',h
allocate (t(0:NI), y(0:NI))

t(0)=0
yo=1
k1=0
k2= -16*h**3
y1 = yo + h/2 *( k1+ k2)
do i=2, NI
t(i)= i*h
y(i)= y(i-1) + (h/2)*(3*f(t(i-1))- f(t(i)))
end do

Real Function f(t,y)
Real t
Real y
f = - 16*t**3*y**2
Return
End

(I manage to do the code but i got the one error and one warning.
Warning: Variable y1 has been given value but never been used.
Error:Function f has been called with too few arguments

Mark44
Mentor
When you include code in your post, put a [code] tag at the beginning and a [/code] tag at the end. This preserves whatever indentation you have used, and makes your code easier to read. I have done this below.
Code:
Program adams
Implicit None
Real, allocatable :: y(:),t(:)
Real:: yo, tmax, h, k1,k2,y1
Integer:: NI, i
Real, external :: f

Print*,  'Enter yo,Tmax,NJ'
h= Tmax/NI
Print*, 'This gives stepsize h=',h
allocate (t(0:NI), y(0:NI))

t(0)=0
yo=1
k1=0
k2= -16*h**3
y1 = yo + h/2 *( k1+ k2) ![color="red"]See comment 1, below[/color]
do i=2, NI
t(i)= i*h
y(i)= y(i-1) + (h/2)*(3*f(t(i-1))- f(t(i))) !![color="red"]See comment 2, below[/color]
end do

Real Function f(t,y)
Real t
Real y
f = - 16*t**3*y**2
Return
End
(I manage to do the code but i got the one error and one warning.
Warning: Variable y1 has been given value but never been used.
Error:Function f has been called with too few arguments
1. Instead of y1, you should probably be using y(1), the first element of your array. You should delete the declaration of y1 up at the top as well.
2. Your function f needs to be called with two arguments. You are calling it with one argument.
Here's what you have: f(t(i-1))- f(t(i)).
What you should probably have is this: f(t(i-1), y(i - 1))- f(t(i), y(i)).

1 person
When i test my code by entering
yo=1
Tmax= 2 (same Tmax=Tend)
NJ=20 (same NJ=NI)
This gives the h stepsize =0.10000
but at the same time it display Run-time error showing
Error 112,Reference to undefined variable, array element or function result(/UNDEF)
F - in file adams.f95 at line 29 [+0089]
main - in file adams.f95 at line 22 [+0531]
IS MY CODE INCORRECT OR I DID NOT TEST THE CODE PROPERLY?

Mark44
Mentor
I'm not positive about this, but I think the problem you're having is caused by declaring f as external. IOW, I would change this line --

Real external :: f

to this--
Real :: f

External implies to me that the definition for the function is in another file, which isn't the case in your code.

hi, I deleted the external and used Real :: f and tested with same number 1,2,20
but still giving same error: displaying Run-time error showing
Error 112,Reference to undefined variable, array element or function result(/UNDEF)
F - in file adams.f95 at line 39 [+0089]
main - in file adams.f95 at line 31 [+0531]

Mark44
Mentor
I didn't notice this before, but you're missing a proper end statement for your function. It should look like this:
Code:
  Real Function f(t,y)
Real t
Real y
f = - 16*t**3*y**2
Return
End [color="blue"]Function f[/color]

I changed to End Function f , but the problem still not solved

Run-time error points errors at
F - at line 39: f = - 16*t**3*y**2
main - at line 31 : y(i)= y(i-1) + (h/2)*(3*f(t(i-1), y(i - 1))- f(t(i), y(i)))

bigfooted
Gold Member
in the absence of a decent debugger, the simplest thing you can do is to add a lot of write statements, outputting all the variables used during the calculation. For instance, write out this during the do loop, after initializing t(i):
i, t(i), t(i-1)

I added this code after do loop
write(10,*) i, t(i),t(i-1) ! This is line 29
Still giving Run-time error but this time error at line 29.

Would you please tell where else do i need to add write statements

Implicit None
Real, allocatable :: y(:),t(:)
Real:: yo, tend, h, k1,k2
Integer:: NI, i
Real,external ::f

!Asking to enter the initial vaule of yo, final time and numbers of step
Print*, 'Enter yo,Tend,NI'
h= Tend/NI
Print*, 'This gives stepsize h=',h
allocate (t(0:NI), y(0:NI))

!Initial Conditions
t(0)=0
yo = 1

!After using runge kutta method, found out k1 =0 and k2= -16h^3,
k1=0
k2= -16*h**3

!we know that y(n+1) =y(n) + h/2(k1+K2) at n=0
y(1) = yo + h/2 *( k1+ k2)

! Loop through the number of steps to calculate the following at each step
do i=2, NI
t(i)= i*h
write(10,*) i, t(i),t(i-1)
!Second order Adam bashforth for all n
y(i)= y(i-1) + (h/2)*(3*f(t(i-1), y(i - 1))- f(t(i), y(i)))
end do

!declaring function
Real Function f(t,y)
Real:: t
Real:: y
f = - 16*t**3*y**2
Return
End Function f

(This is my program so far.)

Mark44
Mentor
Code:
do i=2, NI
t(i)= i*h
write(10,*) i, t(i),t(i-1)
!Second order Adam bashforth for all n
y(i)= y(i-1) + (h/2)*(3*f(t(i-1), y(i - 1))- f(t(i), y(i)))
end do
In the first iteration of your loop, when i = 2, this is what is happening:
t(2) gets set to 2 * .1
The write statement prints 2, .2, and some garbage value for t(1). You get a garbage value because t(1) has never been initialized.

y(2) gets set to y(1) + .1 * (3 * f(garbage, y(1)) - f(.2, y(2))

In the second red part, you're passing y(2) as the argument, but that value is not known yet.
y(i)= y(i-1) + (h/2)*(3*f(t(i-1))- f(t(i)))

I changed this to what you see above, because your function f needs to have two arguments, and in your first code, you have only one argument. You need to check your notes for the Adam-Bashforth algorithm to see what should go in the second call to your function f. I was only guessing as to what should go there, and my guess is probably wrong.

y(i) = y(i-1) + (h/2)*(3*f(t(i-1), y(i - 1))- f(t(i-2), y(i-2)))
and i added t(1) = h
also i changed yo to y(0) and its working now :) Thank you very much Mark44

Mark44
Mentor
You're welcome!

Now i want to plot this partial derivative ∂f/∂y = |-32 (4t^4 +1)^-1 t^3| against t using fortran to generate a file or something for the matlab to plot the graph. Does fortran plot the graph?

Last edited:
Mark44
Mentor
Fortran the programming language doesn't have any graphics capabilities, but there are libraries that you can link your Fortran code to that can do plotting.

It would probably be easier for you to write Fortran code that wrote the data points to a file, and then use that file as input for Matlab to plot it.

What do you mean by libraries sir?
Would you please demonstrate some Fortran code as an example for the Matlab to plot it.

Mark44
Mentor
What do you mean by libraries sir?
A library is a collection of subroutines and functions that are compiled into object code, and that you can link your program to.
Would you please demonstrate some Fortran code as an example for the Matlab to plot it.
When the program you wrote is finished, there are two arrays that are completely initialized: the t array and the y array.

In addition to displaying this data in your program, you could use a write statement to store each pair of numbers (t, y) in a file. You could then use that file as input to a matlab script to graph the data.

partial derivative ∂f/∂y = |-32 (4t^4 +1)^-1 t^3|
how to write this partial derivative ∂f/∂y in fortran.
my adam bashforth second order scheme interval of absolute stabilty: -1<λh<0
∂f/∂y= |λ|
so, h< 1/|λ|
h<1/ |-32 (4t^4 +1)^-1 t^3|
i need to plot ∂f/∂y against time
fortran code:
do i = 0
t(i) = i*h
∂f/∂y = |-32 (4t^4 +1)^-1 t^3|
∂f/∂y=|λ|
end do
write(10,*) "plot (time, |λ|)"
i got soo many errors

Mark44
Mentor
partial derivative ∂f/∂y = |-32 (4t^4 +1)^-1 t^3|
how to write this partial derivative ∂f/∂y in fortran.
my adam bashforth second order scheme interval of absolute stabilty: -1<λh<0
∂f/∂y= |λ|
so, h< 1/|λ|
h<1/ |-32 (4t^4 +1)^-1 t^3|
i need to plot ∂f/∂y against time
fortran code:
do i = 0
t(i) = i*h
∂f/∂y = |-32 (4t^4 +1)^-1 t^3|
∂f/∂y=|λ|
end do
write(10,*) "plot (time, |λ|)"
i got soo many errors
This doesn't look much like Fortran code. You can't use ∂ in a variable name, nor can you use Greek letters such as λ.
You can't assign a value to an expression. IOW, you can't do this:
∂f/∂y = <some value>

You can't do this, either:
df/dy = <some value>

Your variable name has to start with a letter of the alphabet, and can't include symbols such as +, =, *, or /.

Your do loop is missing a required part: do i = 1, NI

I don't know what you're trying to do with this code --
Code:
∂f/∂y = |-32 (4t^4 +1)^-1 t^3|
∂f/∂y=|λ|
Aside from the already mentioned problems with illegal variable names, why are you assigning a value to df/dy, and then assigning a different value? That doesn't make any sense.

Fortran doesn't understand math symbols such as | | for absolute value. If you need the absolute value of some expression, use the abs() intrinsic function.

In your Fortran code here, you are using a variable, t, that hasn't been initialized. You are forgetting that you have an array named t, whose values are t(0), t(1), t(2), ..., t(NI). The array variable is what you should be using.

The biggest mistake is that you are writing brand-new code, when all you need to do is open a file for writing output, and then write the variables that you have already calculated in your previous version. To do this WRITE those t and y values into the file you opened.

Thanks mark44, i will come back later for this question