- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Steve:

I ran into some interesting Fortran behaviour yesterday.

I declared L as a real and it used it to describe length.

Then later I added a write statement that had (x(L),L=1,N) - I was not thinking

it compiled and did not complain about the second L -- but actually counted weirdly -- I got twice the number of elements from X printed out, each second one was zero.

Took me a while to track down the error.

John

Link Copied

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

John,

First, I find it puzzling that you keep addressing questions to me directly. This is a community forum and many people may have the answer to your question. On top of that, I have no special status here other than as an experienced user, albeit one with some insider knowledge. By addressing me specifically, you may be inhibiting others from responding.

Second, your use is non-standard but the compiler will allow it, unless you enable standards checking. For example:

t.f90(7): warning #6187: Fortran 2008 requires an INTEGER data type in this context.print *, (X(L),L=1,10) ------------^

In the example I tried, it worked as I would expect. Please show a small test case that behaves in the manner you describe.

REAL DO-loop control variables used to be allowed in the standard, but were deleted from the standard as of Fortran 95. DEC/Compaq/Intel Fortran continues to allow it as a non-standard usage.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

subroutine RKNB(N, h, m, t0, dt, L, vt, H20, NT, Freq,NR, X,DX, XStart, ModelA) use Base use Bridge implicit none TYPE (Model), TARGET :: ModelA TYPE (EquationA), TARGET :: Equation1 integer N integer I Integer m INTEGER NT Integer NR Integer K Integer J integer km, km1 REAL (KIND=dp) h REAL (KIND=dp) X(N) REAL (KIND=dp) DX(N) REAL (KIND=dp) z(2) REAL (KIND=dp) tau REAL (KIND=dp) xstart,xf(N),xdf(N), xdd(N) REAL (KIND=dp) t0 REAL (KIND=dp) dt, dtmin REAL (KIND=dp) time REAL (KIND=dp) L REAL (KIND=dp) vt ! Velocity of the truck REAL (KIND=dp) LAxle1 REAL (KIND=dp) LAxle2 REAL (KIND=dp) H20(NT) REAL (KIND=dp) eps(mn1), BGH, eqM, eqB REAL (KIND=dp) Ri(m,mn1) REAL(KIND=dp)Freq(NR,mn1), max,min Real(kind=dp) Defl(m) Real(kind=dp) Velc(m) Real(kind=dp) maxB(100) Real(kind=dp) VBNN(100) logical Axle1On logical Axle2On !----------------------------------------------------------------------------------------------- ! Start points z(1) = 0.0_DP z(2) = 0.0_DP tau = ZERO ModelA%LastY = ZERO max = -10000.0 min = 10000.0 Write(*,100)N,h Write(sRB,100)N,h 100 Format(/,'----------------------------------------------------------------------------------------------------',//,& ' Runge Kutta Nystrom Solution for Bridges!',//,& ' Number of equations :: ',I4,/,& ' Tolerance (m) :: ',F10.5) if(N .ne. EIGHT) then stop 'There are eight equations refer to Fryba(1999) Vibrations of Solids and Structures undermoving loads' else write(*,390) write(sRB,390) 390 Format(/' There are eight equations refer to ::',/,' Fryba, L., (1999) Vibrations of Solids and Structures undermoving loads, Telford: London UK',/) endif do 200 i=1,N if(i .eq. 1) then Write(*,300) Write(sRB,300) 300 Format(' Equation 1 :: Fryba Equation 38 ') call FirstEquation(ModelA, Equation1) else if(i .eq. 2) then Write(*,310) Write(SRB,310) 310 Format(' Equation 2 :: Fryba Equation 39 ') else if(i .eq. 3) then Write(*,320) Write(sRB,320) 320 Format(' Equation 3 :: Fryba Equation 37 ') else if(i .eq. 4) then Write(*,330) Write(sRB,330) 330 Format(' Equation 4 :: Fryba Equation 36 ') else if(i .eq. 5) then Write(*,340) Write(sRB,340) 340 Format(' Equation 5 :: Fryba Equation 46 ') else if(i .eq. 6) then Write(*,350) Write(sRB,350) 350 Format(' Equation 6 :: Fryba Equation 46') else if(i .eq. 7) then Write(*,360) Write(sRB,360) 360 Format(' Equation 7 :: Fryba Equation 52') else if(i .eq. 8) then Write(*,370) Write(sRB,370) 370 Format(' Equation 8 :: Fryba Equation 52',//) endif 200 end do write(*,1101)ModelA%chi,ModelA%chiZero,ModelA%freq1,ModelA%Freq(1,1),ModelA%gamma1,ModelA%freq2,ModelA%gamma2,ModelA%gamma22,Equation1%neta(1),Equation1%neta(2) write(srB,1101)ModelA%chi,ModelA%chiZero,ModelA%freq1,ModelA%Freq(1,1),ModelA%gamma1,ModelA%freq2,ModelA%gamma2,ModelA%gamma22,Equation1%neta(1),Equation1%neta(2) 1101 Format(' Chi Factor Load Ratios :: ',F7.3,/,& ' Chi Zero Factor :: ',F7.3,/,& ' Frequency 1 :: ',F7.3,/,& ' Frequency 1,1 :: ',F7.3,/,& ' Gamma 1 :: ',F7.3,/,& ' Frequency 2 :: ',F7.3,/,& ' Gamma 2 :: ',F7.3,/,& ' Gamma 22 :: ',F7.3,/,& ' Damping Ratio 1 :: ',F7.3,/,& ' Damping Ratio 2 :: ',F7.3,/) if(N .eq. 8) then ! write(*,500) write(srB,500) 500 format(//'----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------',/& ' General Second Order Equation - Solution for a Bridge Problem. ',//,& ' Meaning of the terms ::',//,& ' Count :: The analysis step in integer count.',/,& ' Time :: The time of the analysis point in seconds. At 25 m/s it takes 1.2 seconds to traverse a 30 metre bridge.',/,& ' Tau :: Dimensionless time - 1 unit equals time for front wheels to traverse the bridge.',/,& ' ',/,& '|Count Time TAU | Displacement/Rotation | Velocity/ Angular Velocity | Acceleration / Angular Acceleration | Deflection |',/,& '| | 1 2 3 4 5 6 7 8 | 1 2 3 4 5 6 7 8 | 1 2 3 4 5 6 7 8 | Total |',/) elseif(N .eq. 2) then write(*,510) 510 format(' Count Time XF XF XDF XDF') endif time = t0 LAxle1 = t0 LAxle2 = LAxle1 - H20(1) write(sRA,418) write(*,418) 418 Format("Count",",","Time",",","Tau",",","X5",",","X6",",","X7",",","X8",",","DX5",",","DX6",",","DX7",",","DX8",",","DDX5",",","DDX6",",","DDX7",",","DDX8",",","DY*VBN",",","RBig1",",","RBig2") do 600 i=1,m Ri(i,1) = ZERO Axle1On = .false. Axle2On = .false. if(LAxle1 .gt. ZERO .AND. LAxle1 .lt. L )then AXLE1On = .true. Ri(i,1) = ((ONE/FortyEight)*(pi**FOUR))*(H20(2)/gr)*((Freq(1,1)/Freq(1,1))**TWO) endif if(LAxle2 .gt. ZERO .AND. LAxle2 .lt. L )then AXLE2On = .true. endif if(LAxle1 .gt. L)then !AXLE1On = .false. Ri(i,1) = ZERO endif if(LAxle2 .gt. L)then ! AXLE2On = .false. endif if( Laxle1/L .le. ONE) then eps(1) = Laxle1/L else eps(1) = ZERO endif if( Laxle2/L .ge. ZERO .AND. Laxle2/L .le. ONE ) then eps(2) = Laxle2/L else eps(2) = ZERO endif ModelA%etaA = tau ! set up for equaiton 9.49 dtmin = dt !dt = dt / 100.0 call nystrom_lear_44B(N,i,bridgeF,tau,X,DX,dt,xf,xdf, Equation1, ModelA, xdd) write(*,2091)i, N,(xdd(km),km=1,N) 2091 Format(i7, 2x, i4, 8(1x,F8.4)) if(N .eq. 1) then write(*,400)I,t0,(xf(k),k=1,N),(xdf(km),km=1,N) write(srB,400)I,t0,(xf(k),k=1,N),(xdf(km),km=1,N) write(srA,401)I,t0,(xf(k),k=1,N),(xdf(km),km=1,N) elseif(N .eq. 8) then !write(*,420)I,time,tau,xf(5),xf(6),xf(7),xf(8),(ModelA%ydefl(i)*VBN) 420 Format(I5, 2x, 2(2x,F8.3),5(2x,F20.9)) write(srB,416)I,time,tau,(xf(k),k=1,N),(xdf(km),km=1,N),(xdd(km1),km1=1,N),(ModelA%ydefl(i)*sqrt(VBN)) ! write(*,4170)I,time,tau,(xf(k),k=1,N),(xdf(L),L=1,N),(xdd(L),L=1,N),(ModelA%ydefl(i)*VBN) 4170 Format(i4,F4.0,F4.0,25F9.2) 416 Format('|',I7,1x,2(1x,F11.8),' |',8(1x,F11.8),' |',8(1x,F11.2),(' |',F11.3),7(1x,F11.2),' |',1x,F11.2'|') write(srA,411)I,time,tau,xf(5),xf(6),xf(7),xf(8),xdf(5),xdf(6),xdf(7),xdf(8),xdd(5),xdd(6),xdd(7),xdd(8),(ModelA%ydefl(i)*sqrt(VBN)),ModelA%RBig(i,1),ModelA%RBig(i,2) if(max .lt. ModelA%ydefl(i)*sqrt(VBN)) then max = ModelA%ydefl(i)*sqrt(VBN) endif

Line 196 I originally had km set as L - but L was declared as real, it is in the file Lear.f90. With km it works with L it prints out twice as many results - half 0.0000

I do not have a small program - this is a general second order ODE solver - from the Lear paper from NASA. I am in the process of putting in tolerance checking -- hence the printouts.

Main menu select 2 and the file name is CEDR

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

>>With km it works with L it prints out twice as many results - half 0.0000

Odd, it is ASIF it (using a double precision index) converted xdf and xdd to complex.

It may be that the older compilers treated the io-implied-do variables local in scope to the I/O statement (thus had integer type), the newer compilers export the last value from the scope of the I/O statement to that of the procedure. This behavior is a curious bug IMHO.

Must have been quite confusing to ascertain the problem.

Jim Dempsey

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

...... but not at all confusing if you use standards checking.....the run time error would never have happened.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I took your ZIP and built it in 19.1. I ran it first as-is to see what the expected output was, then rebuilt it substituting L as the implied-DO variable. I got identical results. I have to guess that you made some other change at the same time that affected the behavior.

Jim's theory is an interesting guess, but I am 100% confident that was never the behavior. It's interesting to note that in an I/O implied-DO, the DO variable is the host scope variable and not a statement-scope variable of the same name and type as that in the host, which is the case for array constructors.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Thanks for the comment and the time spent, two of the critical standards checkers were turned on.

Yes it was confusing I had zeros between a set of reals.

But now it has gone away.

Of course the real error not declaring a separate variable for the print statement.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page