Reputation: 11
I am doing my maser thesis on WIND turbine simulation On ANSYS CFX.To calculate a parameter I have to use a code written in FORTRAN. I am facing a very weird type of problem and need your help.The complete fortran code is quite long but I will only post the subroutine in the code that is causing problem.
I am using a subroutine to divide the blade in a no of radial elements.Two types of division is used and the radial positions of the elements are then stored in two 1-D arrays RI and RJ.
Later in the code, I got some error and I traced it back to this subroutine that it is not giving me correct values of RJ .The subroutine is giving correct values of RI. Then I displayed the results of RJ using the same loop in which it is calculated correct values of RJ. Fortunately the values of RJ were correct. Then in the same subroutine, immediately after that loop, I started another loop to display the values of RJ again and unfortunately this time they were not correct incorrect values of RJ even there is nothing between the two loops that could change the values of RJ. seemingly every element of RJ is replaced with the next element of RI. Hence I came to know that here is the error originating. I have rechecked the program and seemingly there is no error and the error is originating somewhere inside the subroutine. I am using another program on fortran without ANSYS CFX to calculate wind turbine performance using same subroutine and this problem is NOT coming in that program although the two subroutines in the two programs are exactly same. I need help in this matter as I am stuck in it for past few days. I am using Intel fortran compiler that comes with INTEL COMPOSER.
The subroutinea are as follows
CALL INIT(M,PI,PREC,R,HUBRAD,RI,RJ)
SUBROUTINE INIT(M,PI,PREC,R,HUBRAD,RI,RJ)
INTEGER:: M
REAL:: PI,PREC,R,HUBRAD
REAL:: RI(41),RJ(41)
!,RRI,RRJ)
CALL LLPOINTS (PI,PREC,R,HUBRAD,M,RI,RJ)
return
End Subroutine
SUBROUTINE LLPOINTS (PI,PREC,R,HUBRAD,M,RI,RJ)
!Input arguments: M,Pi, PREC, R, HUBRAD
!Output arguments : RI, RJ
INTEGER:: M
REAL::PREC,R,HUBRAD
REAL:: RI(41),RJ(41)
INTEGER :: J
character*100 ::string1, string2, string3
CALL MESAGE( 'WRITE', 'subroutine INIT START' )
CALL MESAGE( 'WRITE', "RI RJ DJ")
DO J=1,M+1
IF (J.LT.M+1) THEN
RI(J)=0.5E+00*(1.E+00+HUBRAD/R)-0.5E+00*(1.E+00-HUBRAD/R)
&*COS((J-0.5E+00)*PI/M)
RJ(J)=0.5E+00*(1.E+00+HUBRAD/R)-0.5E+00*(1.E+00-HUBRAD/R)
&*COS((J-1.E+00)*PI/M)
IF (ABS(RI(J)).LT.(1/PREC)) THEN
STOP
ENDIF
ELSE
RJ(J)=1.E+00
END IF
write (string1,*) RI(J)
write (string2,*) RJ(J)
CALL MESAGE( 'WRITE', string1//' '//string2)
END DO
CALL MESAGE( 'WRITE','ri rj')
do j =1,m
write (string1,*) RI(J)
write (string2,*) RJ(J)
CALL MESAGE( 'WRITE', string1//' '//string2 )
end do
CALL MESAGE( 'WRITE', 'subroutine LLINE OK' )
END SUBROUTINE
You would be wondering why LLPOINTS is INSIDE INIT subroutine without any reason. Actually in the original program the subroutine INIT has a lot of other subroutines. I used only LLPOINTS and discarded rest of them as I did not need them
I have checked that my program does not have implicit none in any of the subroutines which according to my limited knowledge should be present. When I added implicit none to all subroutines, a number of compilation errors have occurred and seemingly in those errors, I have found that there were problems related to the declarations of a number of variables . I have resolved these issues and now when all issues are resolved, I have got the following error in compilation which was not coming before implicit none.
Error:unresolved external symbol LLINE referenced in function ACD_Dp.
I dont know how to deal with this error
Upvotes: 1
Views: 1486
Reputation: 7395
The weird behavior might originate from some (incorrect) actual arguments rather than subroutines themselves. To explain this, we first consider a simplified version of INIT()
and LLPOINTS()
as follows:
subroutine INIT ( a, b )
implicit none
real :: a( 5 ), b( 5 )
call LLPOINTS ( a, b )
end subroutine
subroutine LLPOINTS ( a, b )
implicit none
real :: a( 5 ), b( 5 )
integer :: i
print *, "output (1):"
do i = 1, 5
a( i ) = i !! set some values to a(:) and b(:)
b( i ) = i * 100
print *, a( i ), b( i ) !! check the values
enddo
print *, "output (2):"
do i = 1, 4
print *, a( i ), b( i ) !! check the values again
enddo
end subroutine
This program sets some values to a(:)
and b(:)
and prints their values twice for double check (as in the OP's program). Now we consider the main program:
program main
real :: a( 5 ), b( 5 )
call INIT ( a, b )
end
which gives the expected result (with ifort test.f90
with v14.0):
output (1):
1.000000 100.0000
2.000000 200.0000
3.000000 300.0000
4.000000 400.0000
5.000000 500.0000
output (2):
1.000000 100.0000
2.000000 200.0000
3.000000 300.0000
4.000000 400.0000
Next, let us suppose that a
and b
are declared erroneously as scalar variables
program main
real :: a, b
call INIT ( a, b )
end
or even with no declaration (i.e., with default implicit real(a-h,o-z)
rule)
program main
call INIT ( a, b )
end
We then obtain
output (1):
1.000000 100.0000
2.000000 200.0000
3.000000 300.0000
4.000000 400.0000
5.000000 500.0000
output (2):
1.000000 2.000000
2.000000 3.000000
3.000000 4.000000
4.000000 5.000000
whose pattern seems to be very similar to that of the OP's output (i.e., all the elements are shifted by 1 in output (2)). That is, the reason for this weird behavior might be that we are passing scalars and accessing an invalid memory region (assuming that a
and b
are aligned contiguously in memory, with some trailing memory area). If so, memory mapping between main()
and LLPOINTS()
may look like this:
a b NG NG NG NG
---------------------------------------
a(1) a(2) a(3) a(4) a(5)
b(1) b(2) b(3) b(4) b(5)
If this is the case, since a(i+1) = b(i)
, we obtain the weird result in output (2) above. We can confirm this by inserting lines like
if ( loc( a(2) ) == loc( b(1) ) ) stop "trapped (ifort)"
in LLPOINTS()
. And more importantly, if we attach
ifort -check test.f90
option, we can detect this automatically (with segmentation fault). So could you try this option to see whether this is the case...?
Upvotes: 1
Reputation: 11
Yes you are right. I have put the following lines
If ( loc( RJ(1) ) == loc( RI(2) ) ) then
call mesage ('write','trapped (ifort)')
stop
End If
and I have got the error , printing trapped (ifort). But the thing is , I have not declared scalar arguments RI, RJ anywhere. I have always declared them as vectors RI(41) and RJ(41)
Upvotes: 0