Fortran subroutine solving for the velocity and displacement of a spring

  • Fortran
  • Thread starter joseph2015
  • Start date
  • #1
11
2

Main Question or Discussion Point

I have a simple Fortran code for solving velocity and displacement of spring, the code works fine when writing all together without using a subroutine. but as I am learning Fortran I tried to do it using subroutine, but I keep getting errors
appreciate any help in advance.

Fortran:
program msd
implicit none
real, parameter :: tstop=100.
integer i
real, dimension(2000) :: t,y,v

open (2, file = "test.txt")


!v(1)=0.0
!y(1)=1.0
!t(1)=0.0

  do i=1,1000

  call deriv(v,y,t)

  write (2,*) v(i),y(i),t(i)

  end do

close(2)
end program msd

!******************************************************

subroutine deriv(v,y,t)
implicit none
real, parameter :: m=1.,b=0.2,k=1., dt=0.1
real, dimension(2000) :: t,y,v
integer i

v(1)=0.0
y(1)=1.0
t(1)=0.0

    v(i+1) = v(i) +(-(b/m)*v(i)-(k/m)*y(i))*dt
    y(i+1) = y(i) + v(i)*dt
    t(i+1) = t(i)+dt

  v(i)=v(i+1)
  y(i)=y(i+1)
  t(i)=t(i+1)

  end subroutine deriv
 
Last edited by a moderator:

Answers and Replies

  • #2
jtbell
Mentor
15,557
3,519
but I keep getting errors
What are the error messages, exactly? Do they refer to specific lines of code?

[added]

I see an issue which may or may not be related to your error messages.

In the main program, the first pass of your do-loop sets its variable i to 1. Then it calls the subroutine.

The subroutine also has a variable named i, but this is separate and independent of the variable i in the main program. You did not make i an argument of the subroutine, nor did you put it in a 'common' block that is shared by the main program and subroutine.

When you first use i in the subroutine, v(i+1) = ... you have not yet set it to a specific value, therefore it contains a "garbage" value which is effectively random. Therefore v(i) and v(i+i) do not refer to the memory locations that you probably want them to refer to.
 
Last edited:
  • #3
FactChecker
Science Advisor
Gold Member
5,591
2,073
Does your subroutine have the same value of i as your main program?
You may want to pass that as a parameter also.
 
  • #4
11
2
Thank you very much jtbell and FactChecker, the issue was not passing i. I really appreciate your help.
 
  • #5
FactChecker
Science Advisor
Gold Member
5,591
2,073
the issue was not passing i.
I don't see how it could work the way you have it, but I will not argue with success.
 
  • #6
11
2
Dear FactChecker the following is the corrected version that works with your helps :), Thanks

Fortran:
======================================================================
program msd
implicit none
real, parameter :: tstop=100.
integer i
real, dimension(2000) :: t,y,v

open (2, file = "test.txt")

  do i=1,1000

  call deriv(v,y,t,i)

  write (2,*) t(i),y(i),v(i)

  end do

close(2)
end program msd

!******************************************************
subroutine deriv(v,y,t,i)
implicit none
real, parameter :: m=1.,b=0.2,k=1., dt=0.1
real, dimension(2000) :: t,y,v
integer i

v(1)=0.0
y(1)=1.0
t(1)=0.0

    v(i+1) = v(i) +(-(b/m)*v(i)-(k/m)*y(i))*dt
    y(i+1) = y(i) + v(i)*dt
    t(i+1) = t(i)+dt

  v(i)=v(i+1)
  y(i)=y(i+1)
  t(i)=t(i+1)

  end subroutine deriv
 
Last edited by a moderator:
  • Like
Likes FactChecker
  • #7
33,646
5,315
the code works fine when writing all together without using a subroutine. but as I am learning Fortran I tried to do it using subroutine
Since you now have both programming styles working, it might be interesting to compare running times for each. I suspect that the code that uses a subroutine to calculate the derivative will be quite a bit slower than when you do the calculation inline, as in your first attempt. The loop in the main program runs 1000 times, and each iteration incurs the overhead of a subroutine call, something that doesn't happen when the derivative calculation is inline in the main program.

As you're new to programming, optimization is less important than just getting something to run. Also, because modern computers have processors that run in the GHz range, there probably won't be much perceptible difference between the two techniques, but it's something to keep in mind for future programs that spend a lot of time on calculations.
 
  • #8
FactChecker
Science Advisor
Gold Member
5,591
2,073
The loop in the main program runs 1000 times, and each iteration incurs the overhead of a subroutine call, something that doesn't happen when the derivative calculation is inline in the main program.

As you're new to programming, optimization is less important than just getting something to run. ... but it's something to keep in mind for future programs that spend a lot of time on calculations.
I would vote for the code that is easiest to understand and maintain. In this case, the loop can be moved into the called subroutine. Large, computationally intensive, subroutines may have only a small percentage of subroutine-call overhead. Small, utility subroutines may often be inlined.
 
  • #9
11
2
The reason I am looking to understand how to put it in the subroutine, is I am looking to learn how to build larger code in the future and use makefiles to compile.
In terms of how fast i can't tell for now as they both run in a blink
 

Related Threads on Fortran subroutine solving for the velocity and displacement of a spring

  • Last Post
Replies
3
Views
2K
  • Last Post
Replies
3
Views
5K
Replies
2
Views
2K
Replies
10
Views
6K
Replies
4
Views
1K
Replies
6
Views
4K
Replies
4
Views
9K
Replies
3
Views
639
Top