使用python进行ABAQUS批处理-kernel代码
责任编辑:chjiegg     时间:2021-01-27     来源:《技术邻》——王国璞
责任编辑:chjiegg
时间:2021-01-27  来源:《技术邻》——王国璞
分类: 技术分享
浏览量: 560

 在使用python进行ABAQUS批处理-总体思路中, 我们梳理了插件开发需求与流程, 本篇将详细讲述该插件的kernel代码的设计。

 

    通过使用python进行ABAQUS批处理-总体思路的梳理, 我们知道kernel的主函数必须接受四个参数:

  1. foldName: 文件夹名称
  2. mutiple: 处理器数目
  3. to_email: 收件人邮箱
  4. power_off: 计算接收后是否关闭计算机

 

    我们还知道了技术难点, 如何让inp进行队列求解, 而不是一次性提交求解.

    程序主要涉及到一些技术知识:

  1. 文件和文件夹的操作
  2. inp文件提交求解
  3. 发送email
  4. 定时关机
     

    其中文件和文件夹的操作以及定时关闭计算机的相关内容, 网上有很多示例, 只需要注意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


 

发送邮件: 信息构造

    

        我们想要收到的或者发送的信息:
 

  1. 分析的项目名称
  2. 分析开始的时间
  3. 分析结束的时间
  4. 总耗时

 

所以函数需要接受开始时间戳, 结束时间戳, 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)

来源:《技术邻》——王国璞

回复:

Copyright © 2021 .长沙麦涛网络科技有限公司 All rights reserved. 湘ICP备20015126号-2
联系我们