Я не могу понять, как правильно вызвать информацию из моего модуля в программу и заставить вычисления работать? - PullRequest
0 голосов
/ 02 ноября 2018

По сути, мне нужно прочитать файл «sounding.txt», содержащий 100 строк данных. Я читаю эти данные и выполняю расчеты, отличные от этих данных. Я рассчитываю уровень замораживания (FRZ), уменьшение точки росы на 700 МБ (Tdd700), общие итоги (TT), K-индекс (KI и уровень SWEAT (SW). Затем я должен вывести это значение в новый файл данных. Расчеты показаны в коде, и кажется, что почти все правильно, но я получаю несколько ошибок, когда я все компилирую. Ошибки терминала указывают, что символ "Tdd700" конфликтует с символ из модуля "soundingcalcs", что символьный символ "T700" не имеет типа IMPLICIT, что символ "Td700" не имеет типа IMPLICIT, и что в моем аргументе "T850" при "KI = ki_calc (звучание) имеется несоответствие ранга Я не уверен, что делаю неправильно, и буду признателен за любую помощь или совет. Мой модуль:

MODULE soundingcalcs

IMPLICIT NONE

 REAL ::  Tdd700, TT, T850, T500, Td850, T700, Td700
 REAL :: V850, V500, dd500, dd850

   contains

   ! This is where the internal module is located

   !##################################################################
   !This functions will calculate the K-Index.
   ! 
   !Accepts: temperature and dew point at different levels
   !Returns: KI-Index
   !#################################################################

  FUNCTION ki_calc(T850,T500,Td850,Tdd700)

  ! Calculate K-Index

  REAL, INTENT(IN) :: T850,T500,Td850,Tdd700
  REAL:: ki_calc

  ki_calc=((T850)-(T500))+(Td850)-(Tdd700)

  END FUNCTION ki_calc

  !################################################################
  !This subroutine will calculate the SWEAT Index
  !
  !Accepts: Total Totals, wind speed, dew point, and temperature
  !Returns: SWEAT Index value
  !################################################################

  SUBROUTINE sw_calc(Td850,TT,V850,V500,dd500,dd850)

  ! Calculate SWEAT Index

  REAL, INTENT(IN):: Td850,V850,V500,dd500,dd850
  REAL:: sw_value, TT

 sw_value=12.0*(Td850)+20.0*((TT)-49.0)+2.0*(V850) &
   +(V500)+125.0*(sin((dd500)-(dd850))+0.2)

  END SUBROUTINE sw_calc

 END MODULE soundingcalcs

Моя основная программа:

USE soundingcalcs

IMPLICIT NONE

CHARACTER(20), PARAMETER :: datafile = "sounding.txt"
CHARACTER(20), PARAMETER :: outfile = "hw9_NEIFERT.out"
CHARACTER(3) :: stname
REAL :: lat, long, elev, pres, temp, dewp, winddir, sw_value
REAL :: windspd, FRZ=0, MW=0, windmax, Td500, SW, KI
REAL :: T700, Td700, Tdd700, TT850, T500, Td850
REAL, DIMENSION(5,100) :: sounding
REAL, PARAMETER :: pi = 3.14159
INTEGER :: OpenStat=0, InputStat=0, day, mth, yr, hr, stnum
INTEGER :: count=0, i, j, log=0
INTEGER, PARAMETER :: flag = -999

sounding=flag

! Open the GEMPAK sounding file

open (unit=2, file=datafile, status="old", iostat=OpenStat)
IF (OpenStat > 0) STOP "Can't open file"

! Read in header and then read in data as array

read (unit=2, FMT="(8x,A3,15x,I8,10x,I2,I2,I2,1x,I4)") &
   stname, stnum, yr, mth, day, hr

read (unit=2, FMT="(8x,F6.2,14x,F6.2,10x,F7.1)") &
   lat, long, elev

read (unit=2, FMT="(////)")

read (unit=2, FMT=*, iostat=InputStat) sounding

! Set counter and maximum wind speed

DO i=1,100
  temp=sounding(2,i)
  IF (temp==flag) EXIT
  count=count+1
END DO

windmax=MAXVAL(sounding(5,:))

! Find temp, dew point, wind speed, directions

DO j=1, count
  pres=sounding(1,j)
  temp=sounding(2,j)
  dewp=sounding(3,j)
  winddir=sounding(4,j)
  windspd=sounding(5,j)

 IF (temp <= 0 .AND. log == 1) THEN
    FRZ=pres
    log=2
 END IF

  IF (pres == 850) THEN
    T850=temp
    Td850=dewp
    V850=windspd
    dd850=(((winddir)*(pi))/(180))
  END IF

  IF (pres == 700) THEN
    T700=temp
    Td700=dewp
  END IF

  IF (pres == 500) THEN
    T500=temp
    Td500=dewp
    V500=windspd
    dd500=(((winddir)*(pi))/(180))
  END IF

  IF (windspd==windmax) MW=pres

END DO

! Calculate 700 millibars dew point depression

Tdd700=(T700)-(Td700)

! Calculate the Total Totals

TT=((T850)-(T500))+((Td850)-(T500))

! Convert function and subroutine module subprograms into working 
! output values

KI=ki_calc(sounding)

! Open a file to output data

open (unit=3, file=outfile, status="new", iostat=OpenStat)
IF (OpenStat > 0) STOP "Cannot open file"

! Output header and values

write (unit=3, FMT="(6x,A15,4x,A3,10x,A11,1x,I8)") "Station ID:", &
stname, "Station #:", stnum

write (unit=3, FMT="(6x,A15,2x,I2,A1,I2,A1,I2,7x,A11,1x,I4,1x,A3)") &
"Date(MM/DD/YY):", mth, "/", day, "/", yr, "Time:", hr, "Z"

write (unit=3, FMT="(/A10,1x,F6.2,1x,A3,3x,A11,1x,F6.2,1x,A3,3x,&    
A11,1x,F8.2,1x,A1)")"Latitude:", lat, "deg", "Longitude:", long, "deg",&
"Elevation:", elev, "m"

write (unit=3, FMT="(/A16,1x,F6.2,1x,A2)") "Freezing Level:",FRZ,"mb"
write (unit=3, FMT="(A16,1x,F6.2,1x,A38)") "Total Totals:", TT
write (unit=3, FMT="(A16,1x,F6.2,1x,A38)") "K-Index:",KI
write (unit=3, FMT="(A16,1x,F6.2,1x,A2)") "SWEAT Index:", sw_value
write (unit=3, FMT="(A16,1x,F6.2,1x,A2)") "Max Wind Level:", MW, "mb"

! Close files

close(3)

close(2)

END PROGRAM sound_calc

1 Ответ

0 голосов
/ 02 ноября 2018

Если вы use модуль, вы импортируете все его процедуры, типы и переменные.

Итак, ошибка

REAL :: T700, Td700, Tdd700, TT850, T500, Td850
            1
sounding.f90:2.4:

USE soundingcalcs
    2
Error: Symbol 't700' at (1) conflicts with symbol from module 'soundingcalcs', 
use-associated at (2)

сообщает вам, что вы объявляете имя переменной, которое уже занято другой переменной в модуле.

Либо объявляйте переменную только в модуле, не импортируйте ее, либо, если вам нужна другая переменная, присвойте ей другое имя.

Так, например, у вас есть:

module my_mod
    implicit none
    real :: a = 1.0
contains
    function get_a()
        real :: get_a
        get_a = a
    end function get_a
end module my_mod

Тогда, если вам нужна только процедура, вы можете импортировать только:

program my_prog
    use my_mod, only: get_a
    real :: a
    a = 3e2
    print *, a
    print *, get_a()
end program my_prog

Если вам нужна переменная с именем a в вашей основной программе, и она должна отличаться от переменной модуля, и вам также необходим доступ к переменной этого модуля, вы можете сделать что-то вроде этого:

program my_prog
    use my_mod, only: get_a, b=>a
    implicit none
    real :: a
    a = 1.0
    b = 2.0
    print *, a, get_a()
end program my_prog

Вторая ошибка связана с несоответствием рангов, проще говоря: функция ki_calc ожидает 4 аргумента скалярного типа real. Но sounding, который вы указываете в качестве единственного аргумента, представляет собой двумерный массив с формой (5, 100)

Я не знаю, что вы хотите, но, может быть, что-то вроде

KI=ki_calc(sounding(1, 1), sounding(2, 1), sounding(3, 1), sounding(4, 1))

(Это будет означать, что T850 == sounding(1, 1) и T500 == sounding(2, 1) и т. Д.)

...