2016-12-28 6 views
0

У меня есть код FORTRAN 77 из учебника для инженерии, который я хотел бы использовать. Проблема заключается в том, что я не могу понять, как я ввода данных в массивах, которые называются именно: FDAM1(61),FDAM2(61),FPOW1(61),FPOW2(61),UDAM(61) и UPOW(61).Как читать данные в массив

Для справки код был взят из Страница 49 из этой книги: https://books.google.pt/books?id=i2hyniQpecYC&lpg=PR6&dq=optimal%20design%20siddall&pg=PA49#v=onepage&q=optimal%20design%20siddall&f=false

C  PROGRAM TST (INPUT,OUTPUT,TAPE5=INPUT,TAPE6=OUTPUT) 
C 
C  PROGRAM TO ESTIMATE MAXIMUM EXPECTED VALUE FOR ALTERNATE DESIGNS 
C 
C  FDENS(I)= ARRAYS FOR DATA DEFINING DENSITY FUNCTIONS 
C  FDAM1(I)= ARRAY DEFINING DENSITY FUNCTION FOR DAMAGE IN DESIGN 1 
C  DFAM2(I)= ARRAY DEFINING DENSITY FUNCTION FOR DAMAGE IN DESIGN 2 
C  FPOW1(I)= ARRAY DEFINING DENSITY FUNCTION FOR POWER IN DESIGN 1 
C  FPOW2(I)= ARRAY DEFINING DENSITY FUNCTION FOR POWER IN DESIGN 2 
C  UDAM(I)= VALUE CURVE FOR DAMAGE 
C  UPOW(I)= VALUE CURVE FOR POWER 
C 
     DIMENSION FDENS(61),FDAM1(61),FDAM2(61),FPOW1(61),FPOW2(61), 
    1UDAM(61),UPOW(61),FUNC(61) 
C 
C  NORMALIZE DENSITY FUNCTIONS 
C 
     DO 1 I=1,4 
     READ(5,10)(FDENS(J),J=1,61) 
     READ(5,11)RANGE 
     AREA=FSIMP(FDENS,RANGE,61) 
     DO 2 J=1,61 
     GO TO(3,4,5,6)I 
3  FDAM1(J)=FDENS(J)/AREA 
     GO TO 2 
4  FDAM2(J)=FDENS(J)/AREA 
     GO TO 2 
5  FPOW1(J)=FDENS(J)/AREA 
     GO TO 2 
6  FPOW2(J)=FDENS(J)/AREA 
2  CONTINUE 
1  CONTINUE 
C 
C  DETERMINE EXPECTED VALUES 
C 
     READ(5,10)(UDAM(J),J=1,61) 
     READ(5,10)(UPOW(J),J=1,61) 
     DO 20 I=1,6 
     GO TO (30,31,32,33,34,35)I 
30 DO 40 J=1,61 
40 FUNC(J)=FDAM1(J)*UDAM(J) 
     RANGE=12. 
     E1=FSIMP(FUNC,RANGE,61) 
     GO TO 20 
31 DO 41 J=1,61 
41 FUNC(J)=FDAM2(J)*UDAM(J) 
C 
     RANGE=12. 
     E2=FSIMP(FUNC,RANGE,61) 
     GO TO 20 
32 DO 42 J=1,61 
     RANGE=60. 
42 FUNC(J)=FPOW1(J)*UPOW(J) 
     E3=FSIMP(FUNC,RANGE,61) 
33 DO 43 J=1,61 
43 FUNC(J)=FPOW2(J)*UPOW(J) 
     RANGE=60. 
     E4=FSIMP(FUNC,RANGE,61) 
     GO TO 20 
34 E5=8.17 
     GO TO 20 
35 E6=2.20 
20 CONTINUE 
     DES1=E1+E3+E5 
     DES2=E2+E4+E6 
C 
C  OUTPUT 
C 
     WRITE(6,100) 
100 FORMAT(/,1H ,15X,24HEXPECTED VALUES OF VALUE,//) 
     WRITE(6,101) 
101 FORMAT(/,1H ,12X,6HDAMAGE,7X,5HPOWER,9X,5HPARTS,8X,5HTOTAL,//) 
     WRITE(6,102)E1,E3,E5,DES1 
102 FORMAT(/,1H ,8HDESIGN 1,4X,F5.3,8X,F5.3,9X,F5.3,8X,F6.3) 
     WRITE(6,103)E2,E4,E6,DES2 
103 FORMAT(/,1H ,8HDESIGN 2,4X,F5.3,8X,F5.3,9X,F5.3,8X,F6.3) 
10 FORMAT(16F5.2) 
11 FORMAT(F5.0) 
     STOP 
     END 

SUBROUTINE FSIMP 

     FUNCTION FSIMP(FUNC,RANGE,MINT) 
C.... CALCULATES INTEGRAL BY SIMPSONS RULE WITH 
C  MODIFICATION IF MINT IS EVEN 
C.... INPUT 
C  FUNC = ARRAY OF EQUALLY SPACED VALUES OF FUNCTION 
C    DIMENSION MINT 
C  RANGE = RANGE OF INTEGRATION 
C  MINT = NUMBER OF STATIONS 
C.... OUTPUT 
C  FSIMP = AREA 
     DIMENSION FUNC(1) 
C.... CHECK MINT FOR ODD OR EVEN 
     XX=RANGE/(3.*FLOAT(MINT-1)) 
     M=MINT/2*2 
     IF(M.EQ.MINT) GO TO 3 
C.... ODD 
     AREA=FUNC(1)+FUNC(M) 
     MM=MINT-1 
     DO 1 I=2,MM,2 
1  AREA=AREA+4.*FUNC(I) 
     MM=MM-1 
     DO 2 I=3,MM,2 
2  AREA=AREA+2.*FUNC(I) 
     FSIMP=XX*AREA 
     RETURN 
C.... EVEN 
C.... USE SIMPSONS RULE FOR ALL BUT THE LAST 3 INTERVALS 
3  M=MINT-3 
     AREA=FUNC(1)+FUNC(M) 
     MM=M-1 
     DO 4 I=2,MM,2 
4  AREA=AREA+4.*FUNC(I) 
     MM=MM-1 
     DO 5 I=3,MM,2 
5  AREA=AREA+2.*FUNC(I) 
     FSIMP=XX*AREA 
C.... USE NEWTONS 3/3 RULE FOR LAST THREE INTERVALS 
     FSIMP=FSIMP+9./3.*XX*(FUNC(MINT-3)+3.*(FUNC(MINT-2)+FUNC(MINT-1)) 
     1 +FUNC(MINT)) 
     RETURN 
     END 

enter image description here

+0

Добро пожаловать в Stack Overflow. Постарайтесь, чтобы ваши сообщения были краткими. Избегайте приветствия и благодарности. Ваше имя находится под строкой с вашим значком. Название должно вводить проблему, а не широкую тему, которая обозначается тегами. Не просто повторяйте теги в заголовке. Используйте довольно общие и более широкие теги, такие как [tag: fortran], добавьте тег для определенной версии только в случае необходимости, чтобы отличить или указать, что вам не нужно какое-либо решение, использующее более новую версию. –

+0

Некоторые из массивов, о которых вы спрашиваете, рассчитываются автоматически внутри программы. Друг читается буквой 'read'. У вас есть описание формата входных данных? Если да, отредактируйте вопрос, чтобы включить его. –

+0

@VladimirF Спасибо за ваш ответ. Исходный список кодов с данными можно найти в ссылке, указанной в исходном вопросе. Автор просто добавил его под основным кодом, поэтому я запутался ... – Andy

ответ

0

Вот минимальный пример, чтобы помочь вам начать:

C Minimal working example of creaky old FORTRAN I/O 
     PROGRAM ABYSS 
     IMPLICIT NONE 
C 
     REAL FDENS(61) 
     REAL XRANGE 
     INTEGER J 
C 
10 FORMAT(16F5.2) 
11 FORMAT(F5.0) 

909 FORMAT(/, 'BEHOLD! A DENSITY DISTRIBUTION',/) 
910 FORMAT(10(F5.2, 3X),/) 
911 FORMAT(/, 'XRANGE is ', F6.1) 
C 
     CONTINUE 
C 
     READ(5,10) (FDENS(J), J=1,61) 
     READ(5,11) XRANGE 
C 
     WRITE(6,909) 
     WRITE(6,910) (FDENS(J), J=1,61) 
     WRITE(6,911) XRANGE 
C 
     STOP 
     END 

Извините, если вы указали это в F77; Я придерживаюсь стиля кода, опубликованного выше для этого примера. В идеале вы бы использовали F03 или F08 для нового кода или совершенно другого языка, который на самом деле имеет приличные возможности ввода-вывода и богатую стандартную библиотеку. Но я отвлекся.

Этот код будет работать на данных (будьте осторожны, чтобы сохранить пространства):

       0.1 0.3 0.5 0.9 1.30 1.90 2.50 3.20 3.80 4.20 
4.70 5.0 5.1 5.2 5.2 5.1 4.9 4.7 4.6 4.4 4.2 3.9 3.8 3.6 3.4 3.2 
3.0 2.9 2.7 2.5 2.4 2.2 2.1 1.9 1.8 1.6 1.5 1.4 1.2 1.1 1.0 0.9 
0.8 0.7 0.6 0.5 0.4 0.3 0.3 0.2 0.1 0.1     
12. 

производить

BEHOLD! A DENSITY DISTRIBUTION 

0.00 0.00 0.00 0.00 0.00 0.00 0.10 0.30 0.50 0.90 

1.30 1.90 2.50 3.20 3.80 4.20 4.70 5.00 5.10 5.20 

5.20 5.10 4.90 4.70 4.60 4.40 4.20 3.90 3.80 3.60 

3.40 3.20 3.00 2.90 2.70 2.50 2.40 2.20 2.10 1.90 

1.80 1.60 1.50 1.40 1.20 1.10 1.00 0.90 0.80 0.70 

0.60 0.50 0.40 0.30 0.30 0.20 0.10 0.10 0.00 0.00 

0.00 

XRANGE is 12.0 

Если код находится в abyss.f, входные данные в abyss.dat, вы должны иметь возможность построить код с

gfortran -g -Wall -Og -o abyss abyss.f 

и роды т.е аналогичные результаты, запустив

abyss <abyss.dat> abyss.out 

Ключевым моментом следует отметить, что исходный код считывает из блока 5 (традиционно принято, как stdin, теперь официально канонизирован в iso_fortran_env в INPUT_UNIT). В своем собственном коде я бы предложил прочитать из файла данных, поэтому замените литерал 5 на любую переменную, содержащую номер единицы файла, который вы читаете (подсказка: рассмотрим аргумент newunit для команды open, введенной в Fortran 2008. Он решает многолетнюю глупую проблему Fortran, пытаясь найти бесплатный номер устройства ввода/вывода.) Хотя вы можете использовать перенаправление ввода-вывода, оно является субоптимальным; он используется здесь, чтобы показать, как обойти ограничения исходного кода.

Кроме того, ради более поздних поколений и вашего собственного здравомыслия, пожалуйста, избегайте использования недостоверных FORTRAN времен холодной войны, таких как бессмысленность этих пробелов. Если ваши данные заслуживают внимания, стоит добавить разумный формат, который можно легко проанализировать; столбчатые, значения, разделенные пробелами, являются таким же хорошим выбором, как и любой другой. Фортран может получить стандартную библиотеку, которая может читать и писать CSV-файлы примерно в 2156 году (давайте или возьмем столетие), чтобы у вас было много времени на разработку чего-то приличного ...

+1

* Извинения за запись этого в F77 *, но вы просто не могли устоять перед тем, что 'IMPLICIT NONE' могли бы вы! –

+0

Посмотрите, только потому, что я написал его в F77, это не значит, что я должен писать его/bad/F77;) – arclight

Смежные вопросы