Прочитайте файл и найдите индекс значения в массиве в Fortran

Я делаю файл пользовательской подпрограммы Abaqus. Однако при чтении файла я столкнулся с трудностью. Поскольку он основан на Fortran 77, найти точное решение очень сложно. Я намерен прочитать файл, в который включен массив 1X1. Затем, чтобы найти индекс значения в массиве.

Мой код для чтения файла:

open (unit=99,file='D:\SIMULATION\dist.txt',status='old')
read (99,*) dist
close (99)

И код для поиска индекса значения в массиве:

loc=minloc(abs(dist-1),1)

Я думаю, что minloc для Fortran 90, верно? Есть ли в Fortran 77 функция, похожая на minloc?


person Kim    schedule 22.05.2017    source источник
comment
minloc - это f95, но вы не можете использовать abaqus с компилятором только для f77.   -  person agentp    schedule 22.05.2017
comment
Что такое дист? Пожалуйста, покажите больше кода! Покажите декларацию. read (99,*) dist также является Fortran 90. Я не думаю, что вам нужно избегать Fortran 90.   -  person Vladimir F    schedule 22.05.2017
comment
В порядке. благодарю вас. Я попробую использовать Fortran 90 или 95.   -  person Kim    schedule 22.05.2017
comment
возможно вы неправильно поняли. Abaqus работает только с последними компиляторами Intel, поэтому вы уже используете по крайней мере f2003. Ваш файл журнала abaqus покажет версию компилятора. Какая у вас актуальная проблема?   -  person agentp    schedule 22.05.2017
comment
Спасибо. Я неправильно понял. Это не проблема версии компилятора. Вместо этого в функции «minloc» появилось сообщение «В этом контексте требуется аргумент с массивом значений». 'dist' - это массив, сформированный [1,2,3]. Я не знаю, в чем проблема.   -  person Kim    schedule 23.05.2017
comment
Это сообщение об ошибке появляется только в том случае, если вы используете minloc для скалярного значения. Другими словами, код, показанный до сих пор, должен компилироваться и работать нормально, пока dist является массивом. Кроме того, есть отвлекающий маневр в отношении ограничения F77 ... некоторая путаница OP может быть связана с тем фактом, что документы и примеры Abaqus продолжают использовать фиксированное форматирование в стиле F77, хотя любая операция, поддерживаемая используемой версией компилятора Intel, действующий код.   -  person Matt P    schedule 23.05.2017


Ответы (1)


Код, который вы показали, должен компилироваться и работать, как и ожидалось. Я предполагаю, что вы на самом деле читаете массив 1xN и что, когда вы сказали "1X1", это была опечатка, иначе нет смысла использовать minloc.

Однако сообщение об ошибке, о котором вы сообщили в комментарии (An array-valued argument is required in this context), возникает только в том случае, если вы используете встроенную функцию minloc для скалярного значения. Таким образом, я предполагаю, что вы не объявляли dist как массив. Вот краткий пример того, что я имею в виду:

! The contents of 'values.txt' are: -3.1, 4.1, 5.9, 2.6, -5.4
! Values may be separated by commas or blanks.

program get_min_dist
    implicit none
    real :: x                   ! <-- Cannot be used to represent an array.
    real, dimension(5) :: a     ! <-- An array of 5 reals. Do this instead.
    integer :: loc, funit1

    open(newunit=funit1, file="values.txt", status="old")
    read(funit1,*) x
    rewind(funit1)
    read(funit1,*) a
    close(funit1)

    loc = minloc(abs(a-1),1)    ! <-- I'm assuming there is a reason to 
                                ! subtract 1 from all values in the array

    ! loc = minloc(abs(x-1),1)  ! <-- Error 'An array-valued arg is required`
    print*, "x=",x
    print*, "a=",a
    print*, "index=", loc
    print*, "value=", a(loc)
end program get_min_dist

С read(funit1,*) x первое значение будет присвоено при чтении файла, что приведет к появлению сообщения об ошибке, которое вы видели. Однако с массивом a вы получите ожидаемый результат.

Ваше замешательство относительно необходимости использования кода, совместимого с F77, может быть связано с тем, что Abaqus продолжает предоставлять примеры и документы с фиксированным форматированием в стиле F77 и требует, чтобы исходный код Fortran был снабжен .f или расширение .for1. По умолчанию это расширение указывает ifort ожидать код фиксированного формата2. Однако любые функции Fortran, поддерживаемые используемой вами версией компилятора, по-прежнему действительны — даже в фиксированном формате, если вам это необходимо. Дополнительные сведения о доступности функций различных версий Fortran см. в документации (Intel Fortran).

1 Я был бы рад узнать, можно ли это как-то изменить, например. чтобы разрешить расширение .f90.

2 Этот параметр можно изменить в файле среды Abaqus, по крайней мере, для версий, которые я использовал (6.9–6.14). Я не думаю, что это изменилось с новыми выпусками, но может быть. Я не рекомендую изменять его, если вы делитесь средой с другими пользователями без их согласия, особенно для новичков.

person Matt P    schedule 23.05.2017
comment
вы можете поместить директиву в локальный abaqus_v6.env файл и не беспокоить других пользователей. ( compile_fortran = compile_fortran+["-free",] вроде работает.) - person agentp; 23.05.2017
comment
@agentp Хороший вопрос, это тоже работает. Все, что угодно, лишь бы избежать фиксированного формата. - person Matt P; 23.05.2017
comment
Спасибо. Я решил свою проблему в соответствии с вашим советом. - person Kim; 25.05.2017
comment
Хорошо! Кроме того, помните совет VladimirF и HighPerformanceMark предоставить минимальный рабочий пример (MWE), чтобы в следующий раз на ваш вопрос можно было ответить гораздо быстрее. - person Matt P; 25.05.2017
comment
@agentp, я только что нашел директиву !DIR$ FREEFORM. Нет необходимости помещать отредактированные файлы .env с -free в cwd, а также никаких изменений в системном файле .env по умолчанию. Ницца. - person Matt P; 24.06.2017