mangesh
mangesh

Reputation: 61

Fortran code returns 0 for every calculation in the loop

Can anyone help me to find where I am going wrong about writing this code

    program time_period
    ! This program calculates time period of an SHM given length of the chord
    implicit none
    integer, parameter:: length=10
    real, parameter :: g=9.81, pi=3.1415926535897932384
    integer, dimension(1:length)::chordlength
    integer :: l
    real :: time
    do l= 1,length
    time = 2*pi*(chordlength(l)/(g))**.5
    print *, l, time
    enddo
    end program

Result:

1 0.00000000E+00
2 0.00000000E+00
3 0.00000000E+00
4 0.00000000E+00
5 0.00000000E+00
6 0.00000000E+00
7 0.00000000E+00
8 0.00000000E+00
9 0.00000000E+00
10 0.00000000E+00

Screenshot of code and result

Upvotes: 1

Views: 371

Answers (3)

John Alexiou
John Alexiou

Reputation: 29244

The code below does not answer your question (since you already did that). But it does address some issues with the design of the code.

As a next step, lets say you want to use a) a function for the calculation, b) have some standard length values to display the period and c) input a custom length for calculation.

Fortran allows for the declaration of elemental functions which can operate on single values or arrays just the same (with no need for a loop). See the example below:

elemental function CalcTimePeriod(chord_length) result(period)
! Calculate the SHM time period from the chord length   
real, parameter :: g=9.80665, pi=3.1415926535897932384
real, intent(in) :: chord_length
real :: period

    period = 2*pi*sqrt(chord_length/g)

end function

So I am posting the code below in hopes that you can learn something new with modern Fortran.

scr

program SHM_CalcTime
implicit none

! Variables
integer, parameter :: n = 10
real, dimension(n) :: gen_lengths, periods
real :: input_length
integer :: i

! Example calculation from generated array of chord lengths
! fill an array of lengths using the formula len = 1.0 + (i-1)/2
gen_lengths = [ (1.0+real(i-1)/2, i=1, n) ]
! calculate the time periods for ALL the lengths in the array
periods = CalcTimePeriod(gen_lengths)

write (*, '(1x,a14,1x,a18)') 'length', 'period'
do i=1,n
    write (*, '(1x,g18.4,1x,g18.6)') gen_lengths(i), periods(i)
end do
input_length = 1.0
do while( input_length>0 )
    write (*,*) 'Enter chord length (0 to exit):'
    read (*,*) input_length
    if(input_length<=0.0) then
        exit
    end if
    write (*, '(1x,g18.4,1x,g18.6)') input_length, CalcTimePeriod(input_length)        
end do

contains

elemental function CalcTimePeriod(chord_length) result(period)
! Calculate the SHM time period from the chord length   
real, parameter :: g=9.80665, pi=3.1415926535897932384
real, intent(in) :: chord_length
real :: period

    period = 2*pi*sqrt(chord_length/g)

end function

end program SHM_CalcTime

On a final note, see that programs can have internal functions declared after a contains statement, with no need for an explicit interface declaration as you would with older Fortran variants.

Upvotes: 0

mangesh
mangesh

Reputation: 61

@High Performance Mark

i worked it the following way

program time_period
! This program calculates time period of an SHM given length of the chord
implicit none
integer, parameter:: length=10
real, parameter :: g=9.81, pi=3.1415926535897932384
integer, dimension(1:length)::chordlength
integer :: l
real, dimension(1:length) :: timeperiod

  do l= 1,length
  print *, 'Enter ChordLength', l
  read *, chordlength(l)
  timeperiod(l) = 2*pi*(chordlength(l)/g)**.5
  enddo
  do l=1,length
  print *, l, timeperiod(l)
  enddo
  end program

its giving me results but asking to type the chord lengths...appreciate your help

Upvotes: 1

High Performance Mark
High Performance Mark

Reputation: 78306

If the chord lengths you're interested are the integer values 1,2,...,10 you hardly need an array to store them. Further, if what you are interested in are the SHM period lengths for each of those 10 chord lengths, it strikes me that you should have an array like this:

real, dimension(length) :: shm_periods

which you would then populate, perhaps like this:

do l= 1,length
    shm_periods(l) = 2*pi*(l/g)**.5
    print *, l, shm_periods(l)
enddo

Next, you could learn about Fortran's array syntax and write only one statement to assign values to shm_periods.

Upvotes: 3

Related Questions