PDA

View Full Version : How does the Fortran90 function floor not have a main type?


Simfish
Oct4-11, 08:52 PM
/home/disk/p/atms380/xx/October-Runs/timeManMod/SourceMods/time_manager.F90(664):
error #6404: This name does not have a type, and must have an explicit
type. [FLOOR]
tmd = day_earth/PLANET_DAY_RATIO - floor(day_earth/PLANET_DAY_RATIO)


I'm running Fortran 90 with the ifort compiler. As far as I can tell, floor is a function introduced in Fortran 90

Using Fortran compiler: ifort -O -I/home/disk/eos11/bitz/cam3.1/cam1/models/utils/esmf -I/home/disk/eos11/bitz/cam3.1/cam1/models/utils/esmf/src/include -I/home/disk/eos11/bitz/cam3.1/cam1/models/utils/esmf/build/linux_intel -I/home/disk/eos11/bitz/cam3.1/cam1/models/utils/esmf/include -I/home/disk/eos11/bitz/cam3.1/cam1/models/utils/esmf/src/Infrastructure/mpiuni
Fortran Compiler version:
Intel(R) Fortran Intel(R) 64 Compiler Professional for applications running on Intel(R) 64, Version 11.1 Build 20091130 Package ID: l_cprof_p_11.1.064

Mark44
Oct5-11, 01:05 AM
The compiler seems to be complaining that the PLANET_DAY_RATIO thing in the call to the floor intrinsic doesn't have a type. A workaround might be to define it as a parameter.

uart
Oct5-11, 01:11 AM
That's strange, it should recognize "floor()"

Can you test if int() and nint() work?

Simfish
Oct5-11, 01:12 AM
I see - thanks very much for the reply!

Here is the subroutine. I defined PLANET_DAY_RATIO within the subroutine. Am I doing it wrong?


subroutine get_curr_date(yr, mon, day, tod, offset)

! Return date components valid at end of current timestep with an optional
! offset (positive or negative) in seconds.

implicit none

! Arguments
integer, intent(out) ::&
yr, &! year
mon, &! month
day, &! day of month
tod ! time of day (seconds past 0Z)

integer, optional, intent(in) :: offset ! Offset from current time in seconds.
! Positive for future times, negative
! for previous times.

! Local variables
character(len=*), parameter :: sub = 'get_curr_date'
integer :: rc
type(esmf_date) :: date
type(esmf_time) :: off
integer :: ymd
integer :: leap_days
integer :: yZero
integer :: day_earth
float :: PLANET_DAY_RATIO

(stuff)

yr = ymd/10000
mon = mod(ymd, 10000) / 100
day = mod(ymd, 100)
PLANET_DAY_RATIO = 0.5 !0.5 is for spinning twice as fast, or 43200 seconds
yZero = start_ymd/10000
leap_days = (yr -yZero)/4
day_earth = day_earth + 365*(yr -yZero) + leap_days
tmd = day_earth/PLANET_DAY_RATIO - floor(day_earth / PLANET_DAY_RATIO)

end subroutine get_curr_date

Simfish
Oct5-11, 01:13 AM
That's strange, it should recognize "floor()"

Can you test if int() and nint() work?

mod() definitely works, so I'm pretty sure that floor() should work too

uart
Oct5-11, 04:07 AM
Hi simfish. I'm not real big on Fortran but when I have used it I've generally had problems whenever I've tried to mix integers and reals in the same expression. Honestly I've given up on trying to figure out the whys and where-fores and now I simply assign all integers to a temporary real before using them in a mixed expression.

Something like

integer :: day_earth
real :: day_earth_tmp, PLANET_DAY_RATIO

...
day_earth_tmp = day_earth
tmd = day_earth_tmp/PLANET_DAY_RATIO - floor(day_earth_tmp / PLANET_DAY_RATIO)

Simfish
Oct5-11, 04:10 AM
Ah okay - thanks for the suggestion! I'll try to see if that works tomorrow.