首頁 > 軟體

python中如何呼叫ansys

2023-02-20 06:00:21

python呼叫ansys

最近做了一個小專案,用python程式碼進行ansys的二次開發,重點是如何使用python呼叫ansys.程式碼如下:

import os
path = 'E:/test'
os.chdir(path)
ansys = r'"D:"Program FilesANSYS Inc"v211ansysbinwinx64MAPDL.exe""  -p ansys -dis -mpi INTELMPI -np 2 -lch -dir "E:test" -j "test" -s read -l en-us -b -i "E:test1model.txt" -o "E:testOutputfile.out""'
os.system(ansys)

當然了,這麼長的一串程式碼肯定不是人手打的,因為肉眼分辨不出來的空格實在太多了。

具體命令在這裡,看圖

點選tool的Display Command Line

複製路徑,最後一行

但是,直接的複製寫程序式碼是沒有用的,因為Python識別不了空格,以及跳脫字元造成的誤解,具體怎麼改正可以看上述程式碼。

我在偵錯程式碼中還遇到了ansys lock的問題,如圖:

原因就是偵錯程式碼同時執行了多個MAPDL檔案且input file都是同一個,導致了ansys lock,因為可以看到每次執行程式碼都會產生一堆.log,.bat,.err檔案,一般這些檔案不會影響程式碼的執行,但是下圖的.lock檔案會是個bug,刪除執行產生的不相干檔案就可以了

利用python執行Ansys Apdl

版本要求

按照官網要求,ANSYS 2021以上,python 3.63.8,以下預設使用者電腦已經安裝ansys2021,python3.63.8,直譯器建議選用pycharm

pymapdl安裝流程

安裝pymapdl包(目前ansys-mapdl-core包只支援這幾個版本),通過清華映象安裝,能夠得到完整的包,否則由於下載超時會中斷,且無法下載到最新的pymapdl-corba模組導致無法實現python連線mapdl

pip install ansys-mapdl-core -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install ansys-mapdl-reader -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install ansys.api.mapdl.v0 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install protobuf -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install grpcio -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install grpcio-tools -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pyaedt -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install ansys-dpf-core -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install ansys-dpf-post -i https://pypi.tuna.tsinghua.edu.cn/simple

測試pymapdl是否安裝成功

from ansys.mapdl.core import launch_mapdl
mapdl = launch_mapdl()
print(mapdl)

若成功,則會顯示ansys版本以及mapdl版本

初始設定和本地啟動mapdl

import os
from ansys.mapdl.core import launch_mapdl
path = os.getcwd()
mapdl = launch_mapdl(run_location=path+'working', exec_file=r"D:setup_position_1ansys2021r1ANSYS Incv211ansysbinwinx64ANSYS211.exe",additional_switches="-smp")
print(mapdl)

啟動失敗原因:

  • pymapdl工作目錄應在當前python工作目錄下,可以按照如上程式碼設定 run_location=path+‘working’
  • 若找不到系統中安裝的mapdl,則可以指定ansys路徑
  • 當遇到許可證問題,如mapdl超時等問題時,使用語句:additional_switches=“-smp”
  • 推薦使用版本為ansys2021 r1(本人目前使用沒有問題的版本)

PyMAPDL語法

pymapdl語法於ansys apdl語法基本一致,詳情可參考二者的官方檔案,以下給出一些範例:

mapdl.clear()
# define element and material
mapdl.prep7()
mapdl.units("SI")  # SI - International system (m, kg, s, K).

# define a ET30 and ET130 element type
mapdl.et(1, "FLUID30", kop2=1)
mapdl.et(2, "FLUID130", kop1=1)

# Define a material (nominal steel in SI)
mapdl.mp("SONC", 1, 1500)  # sonc in m/s
mapdl.mp("DENS", 1, 1000)  # Density in kg/m3
mapdl.mp("SONC", 2, 1500)  # sonc in m/s
mapdl.mp("DENS", 2, 1000)  # Density in kg/m3

工具庫

本批次程式檔案移動採用python os,glob以及shutil包,誤差分析方法採用二範數誤差分析:

import os
import shutil

def mkdir(path):
    path = path.strip()
    path = path.strip("\")
    isExists = os.path.exists(path)
    if not isExists:
        os.makedirs(path)

def clearfolder(path):
    path = path.strip()
    path = path.strip("\")
    isExists = os.path.exists(path)
    if  isExists:
        shutil.rmtree(path)
        mkdir(path)

def mycopyfile(srcfile, dstpath, file_num,filenamelist):                       # 移動函數
    if not os.path.isfile(srcfile):
        print ("%s not exist!"%(srcfile))
    else:
        fpath,fname=os.path.split(srcfile)             # 分離檔名和路徑
        if not os.path.exists(dstpath):
            os.makedirs(dstpath)                       # 建立路徑
        shutil.move(srcfile, dstpath + str(file_num)+'-'+fname)          # 移動檔案
        print ("copy %s -> %s"%(srcfile, dstpath +str(file_num)+'-'+ fname))
        filenamelist.append(dstpath + str(file_num)+'-'+fname)

def filename_to_list(filepath):
    file_name_list = list()  # 新建列表
    for i in os.listdir(filepath):  # 獲取filePath路徑下所有檔名
        data_collect = ''.join(i)  # 檔案名字元串格式
        file_name_list.append(filepath+data_collect)  # 將檔名作為列表元素填入
    return (file_name_list)  # 返回列表

def read_ansys_result(filepath, nodenum):
    ansysdata = []
    f = open(filepath, "r")
    data = f.readline()
    data = f.readline()
    for i in range(1, nodenum+1):
        data = f.readline()
        data = data.strip().split()

        ansysdata.append([float(data[1]), float(data[2]), float(data[3])])

    return ansysdata

def read_my_result(filepath, nodenum):
    mydata = []
    f = open(filepath, "r")
    data = f.readline()
    data = f.readline()
    data = f.readline()
    for i in range(1, nodenum+1):
        data = f.readline()
        data = data.strip().split()
        mydata.append([float(data[3]), float(data[4]), float(data[5])])
    return mydata

def cal_2Norm_Err_ofMesh(caldata,thedata):
    nodenum = len(caldata)
    a = 0
    b = 0
    c = 0
    d = 0
    e = 0
    f = 0
    for i in range(nodenum):
        a += pow(caldata[i][0] - thedata[i][0], 2)
        b += pow(caldata[i][1] - thedata[i][1], 2)
        c += pow(a,2)+pow(b, 2)
        d += pow(thedata[i][0], 2)
        e += pow(thedata[i][1], 2)
        f += pow(thedata[i][2], 2)
    a = pow(a, 0.5)
    b = pow(b, 0.5)
    c = pow(c, 0.5)
    d = pow(d, 0.5)
    e = pow(e, 0.5)
    f = pow(f, 0.5)
    realerr = a/d
    imagerr = b/e
    amperr = c/f
    err_list = str(realerr)+"  "+str(imagerr)+"  "+str(amperr)
    return err_list

def write_2Norm_Err_ofMesh(outputfile, ansysnamelist, mynamelist, thenamelist, fileinfolist):
    ansys_res_data = [] # 每一個元素代表一個檔案的結果
    my_res_data = []
    the_res_data = []
    for i in ansysnamelist:

        print(i)
    for i in range(len(ansysnamelist)):
        ansys_res_data.append( read_ansys_result(ansysnamelist[i], fileinfolist[i][2]))
        my_res_data.append(read_my_result(mynamelist[i], fileinfolist[i][2]))
        the_res_data.append(read_my_result(thenamelist[i], fileinfolist[i][2]))

    f = open(outputfile,"w",encoding='GBK')
    f.write("Title="different mesh num err"n")

    f.write("variables="mesh_number","real_err(%)","imag_err(%)","amp_err(%)"n")
    f.write("zone t="ansys-theroy"n")
    f.write("i="+str(len(ansysnamelist))+",f=pointn")
    for i in range(len(ansysnamelist)):
        ans_the=cal_2Norm_Err_ofMesh(ansys_res_data[i],the_res_data[i])
        f.write(str(fileinfolist[i][1])+"  "+ans_the+"n")

    f.write("zone t="my-theroy"n")
    f.write("i="+str(len(ansysnamelist))+",f=pointn")
    for i in range(len(ansysnamelist)):
        my_the = cal_2Norm_Err_ofMesh(my_res_data[i], the_res_data[i])
        f.write(str(fileinfolist[i][1]) + "  " + my_the + "n")

與window的互動介面

使用isubprocess包來呼叫第三方exe程式,範例如下:

import subprocess
command= " AcoFEM.exe AcoHarmicINFEM AcoHarmicINFEM.cfg 0 0 0"
p = subprocess.Popen(command, shell=True)
p.communicate()

需要注意:

  • exe檔案放在python的工作根目錄下是最穩定的,其餘檔案按照程式設計時與exe檔案的目錄關係進行擺放
  • 儘量減少程式中的視窗輸出,如大量的節點資訊在螢幕上輸出,這會導致鎖死
  • 顯示cmd視窗結果儘量使用p.communicate()而不是p.wait()防止輸出鎖死計算停止

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com