使用python進行ABAQUS批處理-kernel代碼
“ 在使用python進行ABAQUS批處理-總體思路中, 我們梳理了插件開發需求與流程, 本篇將詳細講述該插件的kernel代碼的設計。”
通過使用python進行ABAQUS批處理-總體思路的梳理, 我們知道kernel的主函數必須接受四個參數:
-
foldName: 文件夾名稱
-
mutiple: 處理器數目
-
to_email: 收件人郵箱
-
power_off: 計算接收后是否關閉計算機
我們還知道了技術難點, 如何讓inp進行隊列求解, 而不是一次性提交求解.
程序主要涉及到一些技術知識:
-
文件和文件夾的操作
-
inp文件提交求解
-
發送email
-
定時關機
其中文件和文件夾的操作以及定時關閉計算機的相關內容, 網上有很多示例, 只需要注意ABAQUS使用的python版本為python2.7就可以了, 我這里就不贅述了, 僅貼出代碼, 如有不足之處, 請您斧正, 謝謝.
01
—
技術難點: 隊列求解
我們需要知道ABAQUS是如何根據inp生成job 并提交求解的, 這樣我們就需要使用錄制宏的方法或者直接查看.rpy文件來直接獲得這兩個操作對于的源代碼:
mdb.JobFromInputFile( name='Job-1', inputFileName='W:\\temp\\Job-1.inp', type=ANALYSIS, atTime=None, waitMinutes=0, waitHours=0, queue=None, memory=90, memoryUnits=PERCENTAGE, getMemoryFromAnalysis=True, explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE, userSubroutine='', scratch='', resultsFormat=ODB, multiprocessingMode=DEFAULT, numCpus=16, numDomains=16, numGPUs=0) mdb.jobs['Job-1'].submit(consistencyChecking=OFF)
可以看得出雖然只有兩條命令但是參數多的不像話, 我們可以試一下只保留我們關心的參數, 看看其余的參數是否都存在默認值(其實也可以查閱參考文檔確定這兩個函數的參數, 不過我覺得并沒有試一下快捷):
mdb.JobFromInputFile(name='Job-1', inputFileName='W:\\temp\\Job-1.inp', numCpus=16, numDomains=16) mdb.jobs[jobname].submit()
代碼精簡后重新嘗試運行宏, 發現完全可以完成預想的操作.
那么現在的關鍵就是如何找出一個辦法實現等待上一個inp求解完成后再提交下一個inp的方法了. 因為無法預知每個inp的求解時間, 所以強制等待的方法是不可行的.
我的想法是在ABAQUS里面尋找一下, 看看能不能找到相應的內置方法, 如果有這個方法, 那么它理應被放在mdb對象里或者job對象里. Mdb作為ABAQUS的基類, 我們可以先查看它的成員變量與方法.
在ABAQUScae 頁面的cmd工具欄輸入mdb.__members__查看其成員變量:
>>> mdb.__members__ ['acis', 'adaptivityProcesses', 'annotations', 'coexecutions', 'jobs', 'lastChangedCount', 'meshEditOptions', 'models', 'optimizationProcesses', 'pathName', 'version']
在成員變量中我們看見了jobs(用于存儲job對象的), 但是沒有發現我們的目標, 關于等待的.
在ABAQUScae 頁面的cmd工具欄輸入mdb.__methods__查看其成員函數:
>>> mdb.__methods__ ['AdaptivityProcess', 'Annotation', 'Arrow', 'Coexecution', 'CombineOptResults', 'Job', 'JobFromInputFile', 'Model', 'ModelFromAnsysInputFile', 'ModelFromInputFile', 'ModelFromNastranInputFile', 'ModelFromOdbFile', 'OptimizationProcess', 'Text', 'close', 'closeAuxMdb', 'copyAuxMdbModel', 'getAuxMdbModelNames', 'openAcis', 'openAuxMdb', 'openCatia', 'openEnf', 'openIges', 'openParasolid', 'openProE', 'openSolidworks', 'openStep', 'openVda', 'save', 'saveAs', 'setValues']
在成員函數中我們看見了剛才錄制宏所使用的JobFromInputFile, 但是依然沒有關于等待的方法.
如此, 我們只能看看job對象中有沒有關于等待的方法了:
>>> j = mdb.jobs['Job-1'] >>> j.__methods__ ['EnvironmentAsDict', 'clearMessages', 'kill', 'setValues', 'submit', 'waitForCompletion', 'write3DFMUFile', 'writeInput', 'writeNastranInputFile']
我們發現了waitForCompletion, 看起來就像等待這個job完成的樣子.
我們查閱一下幫助文檔:
waitForCompletion()
This method interrupts the execution of the script until the end of the analysis. If you call the waitForCompletion method and the status member is neither SUBMITTED nor RUNNING, Abaqus assumes the analysis has either completed or aborted and returns immediately.
Arguments
None.
Return value
None.
Exceptions
None.
從它的說明我們就知道, 這就是我們需要的方法.
如下代碼, 其第十三行所使用的standard_str即為工具函數, 在ABAQUS名稱標準化工具中有詳細描述.
import os
import os.path
import shutil
import smtplib
import sys
import time
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import job
from abaqus import *
from abaqusConstants import *
from tools.standard import standard_str
def batch_analysis(foldName, mutiple, to_email, power_off):
start = time.time()
fatherdir = os.path.dirname(foldName)
resultdir = os.path.join(foldName, 'Result')
"""
驗證文件夾是否已被建立
"""
try:
os.mkdir(resultdir)
except:
print('directory "Result" already exist!')
"""
獲取文件夾內部所有文件, 遍歷所有文件, 根據后綴名判斷是否是inp文件
對于inp文件, 標準化名稱后提交, 按順序隊列式求解
"""
infor = os.listdir(foldName)
for item in infor:
tempdir = os.path.join(foldName, item)
tempitem = os.path.splitext(item)[0]
extStr = os.path.splitext(item)[1]
if os.path.isfile(tempdir):
if extStr == '.inp':
jobname = standard_str(tempitem)
# mdb.JobFromInputFile(name=jobname, inputFileName=item)
mdb.JobFromInputFile(name=jobname, inputFileName=item, numCpus=mutiple, numDomains=mutiple)
mdb.jobs[jobname].submit()
mdb.jobs[jobname].waitForCompletion()
send_email(start, time.time(), tempitem, to_email)
"""
獲取求解后的文件夾內所有文件,
編制求解信息文件,
定義需要被保存的文件的類型
"""
newinfor = os.listdir(foldName)
f = open('AnalysisInfo.txt', 'w')
file_set = set(['.inp', '.cae', '.sta', '.jnl', '.odb', '.py'])
for item in newinfor:
tempfile = os.path.join(foldName, item)
extStr = os.path.splitext(item)[1]
if os.path.isfile(tempfile):
if extStr in file_set:
shutil.move(tempfile, resultdir)
try:
tempStr = 'file ' + item + ' moved!\n'
except:
tempStr = 'record.txt ' + ' remained for search!\n'
else:
try:
os.remove(tempfile)
tempStr = 'file ' + item + ' deleted!\n'
except:
tempStr = 'record.txt ' + ' remained for search!\n'
f.writelines(tempStr)
f.close()
end = time.time()
# spend = 100000
if power_off:
o = "c:\windows\system32\shutdown -s -f -t 60"
os.system(o)
02
—
發送郵件: 信息構造
我們想要收到的或者發送的信息:
分析的項目名稱
分析開始的時間
分析結束的時間
總耗時
所以函數需要接受開始時間戳, 結束時間戳, job名稱和收件人郵箱:
def send_email(start, end, job, to_email):
spend = end - start
s = spend % 60
m = spend // 60 % 60
h = spend // 60 // 60
start_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start))
end_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(end))
spend_str = '%dH:%dM:%dS' % (h, m, s)
user = 'yours@139.com'
pwd = 'pwd'
try:
msg = MIMEMultipart()
mail_msg = 'The analysis %s began at %s, ended at %s, Total cost %s.' % (job, start_str, end_str, spend_str)
msg.attach(MIMEText(mail_msg, 'html', 'utf-8'))
msg['Subject'] = end_str + ': Analysis of complete'
msg['From'] = user
msg['To'] = to_email
s = smtplib.SMTP_SSL('smtp.139.com', 465)
s.login(user, pwd)
# print(msg.as_string())
s.sendmail(user, [to_email], msg.as_string())
s.quit()
print('Success!')
except Exception as e:
print(e)
期待更多技術干貨, 請關注AbaqusCoder!
如果本文對您有幫助, 期待您的轉發與點亮再看!
工程師必備
- 項目客服
- 培訓客服
- 平臺客服
TOP




















