Fortran subroutine solving for the velocity and displacement of a spring

Click For Summary

Discussion Overview

The discussion revolves around a Fortran code implementation for solving the velocity and displacement of a spring using a subroutine. Participants explore issues related to variable scope, subroutine parameters, and performance considerations between inline calculations and subroutine calls.

Discussion Character

  • Technical explanation
  • Exploratory
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant shares a Fortran code snippet that works without subroutines but encounters errors when attempting to use a subroutine.
  • Another participant points out that the variable 'i' in the subroutine is independent of the variable 'i' in the main program, suggesting that it should be passed as a parameter to avoid using an uninitialized value.
  • A later reply confirms that the issue was indeed related to not passing 'i' to the subroutine, leading to a successful correction.
  • Discussion includes a comparison of performance between using subroutines and inline calculations, with some participants suggesting that subroutine calls may introduce overhead.
  • One participant emphasizes the importance of understanding subroutines for future programming and code organization, indicating a desire to learn about larger code structures and makefiles.

Areas of Agreement / Disagreement

Participants generally agree on the importance of passing parameters correctly to subroutines. However, there is no consensus on the performance implications of using subroutines versus inline calculations, as opinions vary on the significance of optimization versus code clarity.

Contextual Notes

Some limitations include the potential overhead of subroutine calls in performance-sensitive applications and the need for careful management of variable scope and initialization in Fortran programming.

Who May Find This Useful

Individuals learning Fortran programming, particularly those interested in numerical methods and code organization, may find this discussion beneficial.

joseph2015
Messages
14
Reaction score
2
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:
Technology news on Phys.org
joseph2015 said:
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:
Does your subroutine have the same value of i as your main program?
You may want to pass that as a parameter also.
 
Thank you very much jtbell and FactChecker, the issue was not passing i. I really appreciate your help.
 
joseph2015 said:
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.
 
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   Reactions: FactChecker
joseph2015 said:
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.
 
Mark44 said:
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.
 
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
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 59 ·
2
Replies
59
Views
12K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 5 ·
Replies
5
Views
8K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 26 ·
Replies
26
Views
4K