Отправьте задание, дождитесь его завершения и после этого отправьте другое задание

Мне нужно несколько раз запустить один и тот же файл abaqus .inp (слегка измененный в ходе выполнения), и после завершения каждого запуска мне нужно отправить скрипт abaqus python, который будет считывать результаты.

Я сделал следующее:

#run the programme
os.system('abaqus job=file_name cpus=2')

#get results and write them to myresults.txt
os.system('abaqus viewer noGUI=python_name.py')

Однако основная программа выполняет вторую строку до завершения программы, запущенной в первой строке. В результате получаю ошибку. Как я могу это решить?


person jpcgandre    schedule 11.03.2012    source источник
comment
возможный дубликат: stackoverflow.com/ вопросы/8953119/   -  person Sean    schedule 11.03.2012
comment
Да, но мой случай таков: процесс, который вы запускаете, скорее всего, отключится, чтобы работать в фоновом режиме, и в этом случае пример subprocess.Popen + wait, который дал Дор, не поможет.   -  person jpcgandre    schedule 12.03.2012
comment
Это сработало для меня (однако я еще не пробовал интерактив, и, возможно, это сработает): os.system('abaqus job=file_name') PATH='...\\file_name.lck', если не path.exists(PATH ): time.sleep(1) в то время как path.exists(PATH) и path.isfile(PATH) и access(PATH, R_OK): temp = 0 else: odb = openOdb(path='file_name.odb') Надеюсь, это поможет другие   -  person jpcgandre    schedule 12.03.2012


Ответы (7)


Я думаю, вам нужна система ('abaqus job = inputfile.inp интерактивный')

интерактивный не считает системную команду завершенной до тех пор, пока не завершится выполнение abaqus.

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

person glenn_gould    schedule 06.06.2014

Я предполагаю, что проблема здесь не в ожидании подпроцесса (на самом деле он ждет), а в том, что после запуска решателя Abaqus требуется несколько секунд, чтобы удалить некоторые временные файлы и закрыть свой odb. Я предлагаю одно из следующего:

  • запустите решатель из командной строки с «интерактивным», как предложил @glenn_gould

    strCommandLine = 'abaqus interactive job=jobname'  
    subprocess.call(strCommandLine)
    
  • запустить скрипт abaqus python

    strCommandLine = 'abaqus python ScriptToRun.py -- (jobname)'  
    subprocess.call(strCommandLine)
    

    а в ScriptToRun.py используйте waitForCompletion(), как предложил @ellumini

    from abaqus import *
    import job
    import sys
    
    jobname = mdb.JobFromInputFile(sys.argv[-1], sys.argv[-1]+".inp") 
    jobname.submit() 
    jobname.waitForCompletion()
    
  • используйте оператор try для запуска, пока существует файл jobname.023 или jobname.lck, например:

    strCommandLine = 'abaqus job=jobname'  
    subprocess.call(strCommandLine)
    
    while os.path.isfile('jobname.023') == True:
        sleep(0.1)
    

Это был мой первый пост в этом замечательном сообществе, буду рад узнать, если я сделал что-то не так.

person Francisco Cruz    schedule 07.05.2015

Взгляните на модуль subprocess. Методы call ждут завершения процесса. Вы также можете получить гораздо лучший контроль над дочерним процессом, чем с помощью os.system().

person El Barto    schedule 11.03.2012
comment
Привет! Да, есть еще одна тема об этом, но кажется, что это не подходит для моей проблемы, так как я не запускаю вторую строку. Возможно, модуль подпроцесса должен иметь вывод. В моем случае мне просто нужно, чтобы он закончился, потому что он ничего не вернет. Большое спасибо! - person jpcgandre; 12.03.2012
comment
Насколько мне известно, subprocess — текущий рекомендуемый способ работы с системными вызовами (как упомянул Майк @Multimedia в другом ответе). Дело в том, что если abaqus начнет работать в фоновом режиме, это будет означать, что он отсоединяется от процесса, который вызвал подпроцесс. Если это так, как кто-то сказал в другом вопросе, вам следует проверить, как заставить абакус работать на переднем плане. Если это невозможно сделать, вам следует создать собственный цикл, который отслеживает фоновый процесс abaqus, чтобы увидеть его завершение. - person El Barto; 12.03.2012
comment
Я думаю, что аргумент, который вам нужен, - это интерактивный абакус, предположительно, в отличие от фона абака по умолчанию ( www-h.eng.cam.ac.uk/help/amb/programs/fe/faq68/abaqusf2.html ) - person TimStaley; 12.03.2012

Модуль подпроцесса был рекомендован в другом ответе. Это официально рекомендуемый способ сделать это. Тем не менее, более быстрый и простой метод (а также устаревший в Python 3, но все еще отлично работает в 2.x, так что примите это во внимание) — это команды.

import commands
(return_code, output) = commands.getstatusoutput('abaqus job=file_name cpus=2')
person Multimedia Mike    schedule 11.03.2012
comment
Привет! Дело в том, что первая программа ничего не возвращает, ей остается только закончить. Как только вторая линия сделает все остальное. Это то, что я должен делать? subprocess.call([os.system('baqus job=file_name cpus=2')]) subprocess.call([os.system('abaqus viewer noGUI=python_name.py')]) - person jpcgandre; 12.03.2012
comment
В этот момент я немного запутался - похоже, вы хотите вызвать первую команду, заблокировать, пока эта команда не завершится, а затем вызвать вторую команду. Я только что протестировал как os.system(), так и commands.getstatusoutput() — обе они бодро блокируются до тех пор, пока команда не завершит выполнение. Ваша команда запускает фоновые процессы и немедленно возвращается? - person Multimedia Mike; 12.03.2012
comment
Привет! Программа, которую я вызываю, работает как фоновая программа, поэтому, как я читал в другом потоке: запускаемый вами процесс, вероятно, отключается для запуска в фоновом режиме, и в этом случае пример subprocess.Popen + wait, который дал Дор, не поможет. Любые комментарии будут очень признательны. - person jpcgandre; 12.03.2012
comment
У вас есть несколько вариантов: 1) Измените исходный код abaqus, чтобы он не закрывался, пока его подпроцессы не завершатся (возможно, добавьте параметр командной строки для запуска программы в режиме блокировки). 2) Измените abaqus, чтобы он записывал файл во время работы и удалял его по завершении; опросить/выбрать этот файл. 3) Получите PID подпроцессов abaqus и проверьте их завершение, прежде чем продолжить. - person Multimedia Mike; 12.03.2012
comment
ХОРОШО! Я попробую, но, может быть, лучше уточнить мою проблему. Я использую данную программу, которая читает python для управления моим анализом. Таким образом, этот основной скрипт Python вызывает abaqus и отправляет задание (job=file_name), а затем, после того, как abaqus завершает работу, основной скрипт Python отправляет скрипт Python abaqus, который считывает файл результатов abaqus и извлекает некоторые результаты в txt-файл. Наконец, основной скрипт Python прочитает текстовый файл. Моя проблема в том, что основная программа делает это, не проверяя, закончился ли abaqus, и я получаю сообщение об ошибке. - person jpcgandre; 12.03.2012

Насчет работы в фоновом режиме, вы уверены, что это так?

На этом сайте предполагается, что os.system('abaqus job=file_name cpus=2') будет работать на переднем плане.

Использование Abaqus в пакетном режиме Чтобы вызвать систему Abaqus в пакетном режиме, вы должны указать имя файла в ›команде Abaqus. Например, если вы хотите, чтобы myProg.inp выполнялся:

работа = myProg

(Обратите внимание, что расширение не должно следовать за именем файла)

Эта команда должна запустить Abaqus в пакетном режиме. Команда запустит программу на переднем плане. Если вы хотите запустить программу в фоновом режиме, добавьте амперсанд в конец команды:

abaqus job=myProg &

Может быть, есть локальный параметр конфигурации, который принудительно запускает фоновую обработку? Если это так, возможно, вы можете добавить переключатель, чтобы убедиться, что обработка находится на переднем плане.

person Sean    schedule 11.03.2012
comment
ХОРОШО. Это помогло. Поэтому я использовал subprocess.call([os.system('abaqus job=file_name cpus=2')]) subprocess.call([os.system('abaqus viewer noGUI=python_name.py')]), но вторая строка никогда не звонил. Я не знаю, почему это так. Я уверен, что он не читает вторую строку, поскольку, если я вызову вторую строку без первой (вставьте символ комментария), она запустится, и я получу ожидаемые результаты (поскольку выходные файлы существуют). - person jpcgandre; 12.03.2012
comment
Я также получаю аргумент ошибки типа 'int', который не повторяется, если я использую subprocess.call([os.system('abaqus job=file_name cpus=2')]) - person jpcgandre; 12.03.2012
comment
Вау! Не делай этого. :-) Используйте subprocess или os.system(), но не оба вместе. - person Multimedia Mike; 12.03.2012
comment
Да, извините за это. Я все же бегу. хотя второй строки нет. Если я использую subprocess.call(['abaqus job=file_name cpus=2']), я получаю сообщение об ошибке: система не может найти указанный файл... Если я использую os.system, он не запускает вторую строку и зависает. - person jpcgandre; 12.03.2012
comment
Возможно, вам потребуется указать полный путь к abaqus, если его нет на вашем PATH. - person El Barto; 12.03.2012
comment
В самом деле, если вы еще не проверили, первая команда действительно что-то делает (из командной строки она создает файл, верно?). - person Sean; 12.03.2012
comment
Первая команда делает то, что должна делать. Работа заканчивается. Что происходит, так это то, что вторая команда, которая отправит скрипт abaqus python для чтения файла результатов, не запускается. - person jpcgandre; 12.03.2012

не уверен, что вы уже нашли адекватное решение, но объект задания:

Jobxy.waitForCompletion() 

ожидает завершения задания, а затем продолжает выполнение скрипта pyhton; например, с командами, касающимися постобработки. Подробную информацию см. в руководстве пользователя сценариев abaqus...

person ellumini    schedule 03.03.2015

Попробуйте использовать подпроцесс, но без параметра os.call. Вы можете использовать этот метод для запуска Abaqus в фоновом режиме:

import subprocess
path = location of file in any directory 
abaqusCall = 'abaqus job=file_name cpus=2'
runCommand = 'cmd.exe /c ' + abaqusCall
process = subprocess.Popen(runCommand, cwd=path)

Проблема с Abaqus заключается в том, что выполнение анализа занимает много времени, поэтому, если вы попытаетесь запустить файл «python_name.py», чтобы получить результаты, программа может получить ошибки, потому что файл *.odb либо не был еще не создан или не содержит данных, которые необходимо извлечь.

Вы можете использовать команду:

process.wait()

чтобы указать Python дождаться завершения анализа Abaqus перед выполнением вашего «python_name.py», но это приведет к зависанию вашей команды python (или графического интерфейса) до тех пор, пока Abaqus не завершит работу, что займет много времени.

Один из методов, который я использую, — это чтение файла *.sta из Abaqus, в котором есть время решения и прогресс. Таким образом, вы можете написать последовательность для чтения файла, например, каждые 5 секунд, и отслеживать, когда задание завершается, прежде чем выполнять файл извлечения результатов.

Еще один трюк для извлечения данных заключается в том, что пока вы не используете (импортируете) классы из модуля CAE, вы можете запустить свой скрипт Python с помощью этой команды:

#get results and write them to myresults.txt
os.system('abaqus python python_name.py')
person Nader    schedule 14.06.2012