Python 语言创建 ANSYS APDL 命令流


目 录




Blog Links





一、前言


  ANSYS 参数化设计编程 (ANSYS Parameter Design Language —— APDL) 是 一种通过参数化变量方式建立分析模型的脚本语言,它用智能化分析的手段,为用户提供了自动完成有限元分析过程的功能,即程序的输入可根据指定的函数、变量以及选用的分析类型来确定,是完成优化设计和自适应网格的最主要基础。


  显然,APDL 不是编程语言,它只能使 ANSYS 建模自动化,除此以外毫无用处。因此,我们可采用 Python 语言将经常用到的 ANSYS APDL 命令流进行封装,供日后的重复利用。这样,只需要在编写 Python 函数时一次性地了解 APDL 命令流的含义,而不必经常性地接触枯燥且无聊的 APDL 命令流。


  在此不得不吐槽一下,把 APDL 记的滚瓜烂熟有毛线用,至少采用本文这种方式创建 APDL 命令流能提高 Python 的使用技能。好歹 HyperMesh 自动化建模的 Tcl 语言是个脚本语言,用处也不只被局限于 HyperMesh,还可用于其他方面。我就问你个直击灵魂的问题:APDL 贼拉精通后,又能如何?你能拿它干什么,除非你数值模拟世界里只有 ANSYS 。垃圾,呸!经典 ANSYS 是本人最烦的软件,没有之一,简直就是反人类,不但界面难看而且丑陋。以上言论纯属个人观点,不喜欢走就。



Abaqus与Ansys近似对应关系

类别AbaqusAnsys
脚本语言PythonAPDL
命令流文件abaqus.rpyjobname.log
求解器输入文件.inp.cdb(有限元求解文件)
模型数据库文件.cae.db(二进制数据库文件)
结果数据库文件.odb.rst


  在 ANSYS Mechanical APDL 程序启动时,将在当前工作目录内创建 jobname.log 文件,其中 jobname 为用户定义的工作名称,若事先为指定工作名称,则程序采用默认的 file.log、file0.log 或 file1.log 等为 log 文件的名称。



在这里插入图片描述

丑陋且难看的ANSYS经典界面



  用户在 ANSYS 经典界面中进行的每一步操作所对应的 APDL 命令都将存储在这个文件中。.log 为 ASCII 文件,采用任何一款文本编辑软件均可打开 jobname.log 文件。通过,对它的修改编辑,用户可创建新的 APDL 命令文件,用以更方便地实现参数化建模。



在这里插入图片描述

记录APDL命令流的jobname.log文件





二、APDL命令


  ANSYS 软件提供两种工作模式: 人机交互方式 (GUI 方式) 和 命令流输入方式 (Batch 方式) 。


  在 ANSYS 中,输入的 APDL 命令流不区分大小写。通常情况下,为了提高命令流的可读性,约定:在输入的命令流中凡是用户输出的字符都采用小写字母方式,或第 1 个字母大写其余的字母为小写的方式,而 ANSYS 系统中的命令或标签名都采用大写。


  APDL 的基本组成:参数化、宏命令、分支、循环、重复执行和数值。



2.1 帮助文档


  在 ANSYS 经典界面中的菜单栏上,依次单击 Help >> Help Topics ,可弹出在线帮助文档。单击 Command Reference 便可查看各 APDL 命令的格式及相关介绍,如下图所示。


在这里插入图片描述


ANSYS在线帮助文档

  如上图所示,创建结点的 APDL 命令格式为:


N, NODE, X, Y, Z, THXY, THYZ, THZX

  其中,输入参数 NODE 为 Node number to be assigned ,X, Y, Z 为 Node location in the active coordinate system (R, θ, Z for cylindrical, R, θ, Φ for spherical or toroidal)。例如,在当前坐标系下,创建一编号为 107 的结点,且它在当前坐标系下的坐标为 (10,9,7),那么相应的 APDL 命令如下所示。


N, 107, 10, 9, 7, 0, 0, 0


  另外,还可通过搜索神器 Everything,在本地电脑中,搜索到其 pdf 版的帮助文档,如下图所示。


在这里插入图片描述




2.2 命令窗口


  在 ANSYS 经典界面的菜单栏下方的文本输入框为 APDL 命令窗口,用于命令的输入,按回车后执行输入的命令,如下图所示。


在这里插入图片描述


Command Prompt

  例如,在前处理器处(PREP7)于活跃状态时,将上文创建 107 号结点的命令 “N, 107, 10, 9, 7, 0, 0, 0”,复制到命令窗口中,回车后,ANSYS 程序将执行该命令,创建的结点如下图所示。


在这里插入图片描述





2.3 运行宏文件


  用户可将 ANSYS 文件记录在一个宏文件中,有时也称为命令流文件,所谓宏文件就是记录 ANSYS 命令流且拓展名为 .mac 的文件,使用 .mac 为拓展名,可使 ANSYS 在执行该命令时,将其当作一个内部命令一样使用。但最好避免使用这个拓展名,因为它将被 ANSYS 的内部宏所使用。






三、属性


3.1 定义材料属性


def create_material_properties(matnum=None, rho=0, e=0, nu=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:定义线弹性材料属性
    # 参数:matnum为材料编号;rho为质量密度;e为弹性模量;nu为泊松比
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    cmds = [[s1, c1], ]
    if matnum is None:
        matnum = "matmax+1"
        tmps = "*GET,matmax,MAT,,NUM,MAX"
        tmpc = "! 当前最大材料编号<matmax>."
        cmds.append([tmps, tmpc])
    s2 = "MPTEMP,,,,,,,,"
    c2 = "! Defines a temperature table."
    s3 = "MPTEMP,1,0"
    c3 = "! 定义温度表/SLOC=1."
    s4 = "MPDATA,DENS,%s,,%s" % (matnum, rho)
    c4 = "! 设置材性/材料编号<%s>/质量密度<%s>." % (matnum, rho)
    s5 = "MPDATA,EX,%s,,%s" % (matnum, e)
    c5 = "! 设置材性/材料编号<%s>/弹性模量<%s>." % (matnum, e)
    s6 = "MPDATA,PRXY,%s,,%s" % (matnum, nu)
    c6 = "! 设置材性/材料编号<%s>/泊松比<%s>." % (matnum, nu)
    cmds = cmds + [[s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6]]
    return cmds



3.2 定义单元类型


def define_local_element_type(etnum=None, etname="SOLID185"):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:定义单元类型/各单元关键选项均采样默认设置/后续修改
    # Defines a local element type from the element library.
    # 参数:matnum为材料编号;rho为质量密度;e为弹性模量;nu为泊松比
    # 返回:APDL命令流列表
    # *GET,etmax,ETYP,,NUM,MAX         ! 当前最大单元类型号<etmax>
    # ET,etmax+1,SOLID185              ! 定义单元/SOLID185/单元编号<etmax+1>.
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    cmds = [[s1, c1], ]
    if etnum is None:
        etnum = "etmax+1"
        tmps = "*GET,etmax,ETYP,,NUM,MAX"
        tmpc = "! 当前最大单元类型编号<etmax>."
        cmds.append([tmps, tmpc])
    s2 = "ET,%s,%s" % (etnum, etname)
    c2 = "! 定义单元类型/单元类型编号<%s>/单元类别名称<%s>." % (etnum, etname)
    cmds = cmds + [[s2, c2]]
    return cmds


3.3 定义截面/截面属性



  对于一维梁单元,其截面属性应包括所用材料和横截面的几何形状;对于二维板壳单元,其截面属性应包括所用材料和板壳的厚度;对于三维实体单元,其截面属性只需要提供所用材料即可。


  对于一维梁单元,在 ANSYS 中,所提及的截面一般指的是梁的横截面几何形状,它是与 Abaqus 中的 Profile 相对应的。因此,截面/截面形状指梁横截面的几何尺寸,如长宽高等,截面属性除了包括截面形状外,还包括材料属性。



3.3.1 定义梁截面


def create_circular_section(secname, secnum=None, radius=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:定义圆形梁截面/几何尺寸
    # 参数:secname为截面名称;secnum为梁的截面编号/截面形状号;radius为圆的半径
    # 返回:APDL命令流
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    cmds = [[s1, c1], ]
    if secnum is None:
        secnum = "secmax+1"
        tmps = "*GET,secmax,SECP,,NUM,MAX"
        tmpc = "! 当前最大截面编号<secmax>."
        cmds.append([tmps, tmpc])
    s2 = "SECTYPE,%s,BEAM,CSOLID,%s,0" % (secnum,secname)
    c2 = "! 定义实心圆形梁截面/截面编号<%s>/截面名称<%s>." % (secnum,secname)
    s3 = "SECOFFSET,CENT"
    c3 = "! 设置截面偏置/梁杆轴端点位于梁截面形心上."
    s4 = "SECDATA,%s" % radius
    c4 = "! 定义几何尺寸/圆的半径<%s>." % radius
    cmds = cmds + [[s2, c2], [s3, c3], [s4, c4], ]
    return cmds


def create_rectangular_section(secname, secnum=None, width=None, height=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:定义矩形梁截面/几何尺寸
    # 参数:secname为截面名称;secnum为梁的截面编号/截面形状号
    # 参数:width、height分别为矩形的宽度和高度
    # 返回:APDL命令流
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    cmds = [[s1, c1], ]
    if secnum is None:
        secnum = "secmax+1"
        tmps = "*GET,secmax,SECP,,NUM,MAX"
        tmpc = "! 当前最大截面编号<secmax>."
        cmds.append([tmps, tmpc])
    s2 = "SECTYPE,%s,BEAM,RECT,%s,0" % (secnum,secname)
    c2 = "! 定义矩形梁截面/截面编号<%s>/截面名称<%s>." % (secnum,secname)
    s3 = "SECOFFSET,CENT"
    c3 = "! 设置截面偏置/梁杆轴端点位于梁截面形心上."
    s4 = "SECDATA,%s,%s" % (width, height)
    c4 = "! 定义几何尺寸/矩形的宽度<%s>/矩形的高度<%s>." % (width, height)
    cmds = cmds + [[s2, c2], [s3, c3], [s4, c4], ]
    return cmds



3.3.2 定义壳截面属性


def create_shell_section_property(secname, secnum=None, thickness=0.1024, matnum=1024):
    # 功能:定义壳截截面属性
    # 参数:secname为截面名称;secnum为梁的截面编号/截面形状号;thickness为壳的厚度;matnum为材料编号
    # 返回:APDL命令流
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    cmds = [[s1, c1], ]
    if secnum is None:
        secnum = "secmax+1"
        tmps = "*GET,secmax,SECP,,NUM,MAX"
        tmpc = "! 当前最大截面编号<secmax>."
        cmds.append([tmps, tmpc])
    s2 = "SECT,%s,SHELL,,%s,0.0,3" % (secnum, secname)
    c2 = "! 定义板壳截面/截面编号<%s>/截面名称<%s>/Oriention<0.0>/积分点个数<3>." % (secnum, secname)
    s3 = "SECOFFSET,MID"
    c3 = "! 设置截面偏置/板的各结点位于截面中性面上."
    s4 = "SECDATA,%s,%s," % (thickness, matnum)
    c4 = "! 定义板壳属性/板壳的厚度<%s>/材料编号<%s>." % (thickness, matnum)
    s5 = "SECCONTROL,,,,,,,"
    c5 = "! Section Controls."
    cmds = cmds + [[s2, c2], [s3, c3], [s4, c4], [s5, c5], ]
    return cmds



3.3.3 定义实体截面


  与 Abaqus 不同,在 ANSYS 中,各项同性的三维实体单元的实体截面属性无需要单独定义并赋予,只需要指定材料编号即可。




3.4 设置属性



3.4.1 设置一维梁单元的属性


def assign_property_to_beam_elements(compname, matnum=None, secnum=None, etnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:为组件内的全部梁单元指定属性
    # 参数:compname为组件名称;matname为材料编号;secnum为截面编号;etnmu为单元类型编号。
    # 注意:组件的类型必须是单元
    # 返回:APDL命令流
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CMSEL,S,%s" % compname
    c3 = "! 选择组件/组件名称<%s>." % compname
    s4 = "ALLSEL,BELOW,ELEM"
    c4 = "! 选择组件内的全部单元."
    cmds = [[s1, c1], [s2, c2], [s3, c3], [s4, c4], ]
    if matnum is not None:
        # 修改单元属性/修改材料属性
        tmps = "EMODIF,ALL,MAT,%s" % matnum
        tmpc = "! 修改单元属性/修改单元材料编号/新的单元材料编号<%s>." % matnum
        cmds.append([tmps, tmpc])
    if secnum is not None:
        tmps = "EMODIF,ALL,SEC,%s" % secnum
        tmpc = "! 修改单元属性/修改单元截面编号/新的单元截面编号<%s>." % secnum
        cmds.append([tmps, tmpc])
    if etnum is not None:
        tmps = "EMODIF,ALL,TYPE,%s" % etnum
        tmpc = "! 修改单元属性/修改单元类型编号/新的单元类型编号<%s>." % etnum
        cmds.append([tmps, tmpc])
    cmds = cmds + [[s2, c2], ]
    return cmds



3.4.2 设置二维壳单元的属性


def assign_property_to_shell_elements(compname, matnum=None, secnum=None, etnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:为组件内的全部壳单元指定属性
    # 参数:compname为组件名称;matname为材料编号;secnum为截面编号;etnmu为单元类型编号。
    # 注意:组件的类型必须是单元
    # 返回:APDL命令流
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CMSEL,S,%s" % compname
    c3 = "! 选择组件/组件名称<%s>." % compname
    s4 = "ALLSEL,BELOW,ELEM"
    c4 = "! 选择组件内的全部单元."
    cmds = [[s1, c1], [s2, c2], [s3, c3], [s4, c4], ]
    if matnum is not None:
        # 修改单元属性/修改材料属性
        tmps = "EMODIF,ALL,MAT,%s" % matnum
        tmpc = "! 修改单元属性/修改单元材料编号/新的单元材料编号<%s>." % matnum
        cmds.append([tmps, tmpc])
    if secnum is not None:
        tmps = "EMODIF,ALL,SEC,%s" % secnum
        tmpc = "! 修改单元属性/修改单元截面编号/新的单元截面编号<%s>." % secnum
        cmds.append([tmps, tmpc])
    if etnum is not None:
        tmps = "EMODIF,ALL,TYPE,%s" % etnum
        tmpc = "! 修改单元属性/修改单元类型编号/新的单元类型编号<%s>." % etnum
        cmds.append([tmps, tmpc])
    cmds = cmds + [[s2, c2], ]
    return cmds


3.4.3 设置三维体单元的属性


def assign_property_to_solid_elements(compname, matnum=None, secnum=None, etnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:为组件内的全部实体单元指定属性
    # 参数:compname为组件名称;matname为材料编号;secnum为截面编号;etnmu为单元类型编号。
    # 注意:组件的类型必须是单元/另外实体单元的secnum参数无意义
    # 返回:APDL命令流
    secnum = None
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CMSEL,S,%s" % compname
    c3 = "! 选择组件/组件名称<%s>." % compname
    s4 = "ALLSEL,BELOW,ELEM"
    c4 = "! 选择组件内的全部单元."
    cmds = [[s1, c1], [s2, c2], [s3, c3], [s4, c4], ]
    if matnum is not None:
        # 修改单元属性/修改材料属性
        tmps = "EMODIF,ALL,MAT,%s" % matnum
        tmpc = "! 修改单元属性/修改单元材料编号/新的单元材料编号<%s>." % matnum
        cmds.append([tmps, tmpc])
    if secnum is not None:
        tmps = "EMODIF,ALL,SEC,%s" % secnum
        tmpc = "! 修改单元属性/修改单元截面编号/新的单元截面编号<%s>." % secnum
        cmds.append([tmps, tmpc])
    if etnum is not None:
        tmps = "EMODIF,ALL,TYPE,%s" % etnum
        tmpc = "! 修改单元属性/修改单元类型编号/新的单元类型编号<%s>." % etnum
        cmds.append([tmps, tmpc])
    cmds = cmds + [[s2, c2], ]
    return cmds




四、坐标系与工作平面



Python函数

序号函数名称功能
1activate_coordinate_system(csys)激活坐标系
2create_coordinate_system_from_three_points(origin, xpoint, ypoint, csysnumber, csystype, currcsys)三点创建坐标系
3rotate_nodal_coordinate_system(nodes, targetcsys)旋转结点的结果坐标系
4activate_coordinate_system_for_resluts_dispaly(csys)激活结果坐标系
5define_working_plane_from_three_points(origin, xpoint, ypoint, currcsys)三点创建工作平面


  在 Ansys 系统中,有多种坐标系供选择,主要有:总体和局部坐标系、结点坐标系、单元坐标系和结果坐标系。各坐标系的功能/用途如下表所示。



序号坐标系类别用途/功能
1总体和局部坐标系定义几何形状参数 (结点、关键点等) 和空间位置
2结点坐标系定义每个结点的自由度和结点结果数据的方向。(单元结点自由度和全局结点自由度的区别)
3单元坐标系确定材料特性主轴和单元结果数据的方向
4结果坐标系用来列表、显示或在通用后处理操作中将结点和单元结果转换到一个特定的坐标系中


在这里插入图片描述


ANSYS全局直角坐标系


  通常情况下,高维度几何可由低维度几何经一定的操作创建而成,如几何体可由几何面经拉伸、旋转得到。那么,此时就需要提供一个参考平面,来指定几何面的拉伸法线方向。在 ANSYS 中,这个参考平面被称作工作平面;在 Abaqus 中,草图模块(Sketch)的功能类似于这个参考面;在 HyperMesh 中,没有明显与参考面相对应的功能。


  工作平面是一个无限平面,有原点、二维坐标系、捕捉增量和显示栅格。在同一时刻只能定义一个工作平面 (当前定义一个新的工作平面时就会删除已有工作平面)。工作平面是与坐标系独立使用的。例如,工作平面与激活的坐标系可以有不同的原点和旋转方向。


  当进入 ANSYS 程序时,有一个默认的工作平面,即总体笛卡尔坐标系的 x-y 平面。工作平面的 x 轴、y 轴分别取为总体笛卡尔坐标系的 x 轴和 y 轴。例如,由几何面经拉伸方式创建几何体时,几何面必须在某一工作平面上进行创建,这样在拉伸时,程序才知道往哪个方向拉伸,即工作平面的法线方向。



4.1 激活局部坐标系


def activate_coordinate_system(csys):
    # 功能:激活已存在的坐标系
    # 参数:csys为已存在的坐标系的参考号
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "CSYS,%s" % csys
    c2 = "! 激活坐标系/坐标系参考号<%s>." % csys
    cmds = [[s1, c1], [s2, c2], ]
    return cmds
# 示例
# csys = 102  # 激活102号局部坐标系
# cmds = activate_coordinate_system(csys)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



4.2 创建局部坐标系


  在 ANSYS 中,创建局部坐标系的命令有很多,如 LOCAL、CLOCAL 等等,为了方便,我们采用三点法创建局部坐标系,即通过给定三个关键点的坐标,便可在模型空间中唯一确定一局部坐标系,这三个关键点分别是:局部坐标系的坐标原点、局部 x 轴正方向上一点,局部 xy 平面上偏 y 轴正向一点。在 ANSYS 系统中,由三(结)点坐标创创建局部坐标系的命令为 CS,其相关介绍见下图。



在这里插入图片描述


CS命令
(ANSYS_Mechanical_APDL_Command_Reference.pdf)



  综上,我们可以编写名为 create_coordinate_system_from_three_points 的 Python 函数,用于快速生成由三点法创建局部坐标系的 ANSYS APDL 命令流,Python 代码如下:


def create_coordinate_system_from_three_points(origin=[0, 0, 0], xpoint=[1, 0, 0], ypoint=[0, 1, 0], csysnumber=None, csystype=0, currcsys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由3个点坐标创建局部坐标系
    # 参数:origin为原点坐标;xpoint为局部x轴上正方向上一点的坐标;ypoint为局部xy平面上偏+y方向一点的坐标;
    # 参数:csysnumber为新建坐标系的参考号(coordinate system reference number)、其值必须大于10;
    # 参数:csystype为新建坐标系的类型,0为直角坐标系,1为柱坐标系,2为球坐标系;
    # 参数:currcsys为当前活跃的坐标系,即上述三个点坐标所参考的坐标系,默认为0(全局直角坐标系)
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "*GET,ndmax,NODE,,NUM,MAX"
    c2 = "! 当前最大结点编号<ndmax>."
    s3 = "CSYS,%s" % currcsys
    c3 = "! 激活坐标系/坐标系参考号<%s>." % currcsys
    x, y, z = origin
    s4 = "N,ndmax+1,%s,%s,%s," % (x, y, z)
    c4 = "! 新建结点/结点编号<ndmax+1>/结点坐标<(%s,%s,%s)>/坐标系<%s>." % (x, y, z, currcsys)
    x, y, z = xpoint
    s5 = "N,ndmax+2,%s,%s,%s," % (x, y, z)
    c5 = "! 新建结点/结点编号<ndmax+2>/结点坐标<(%s,%s,%s)>/坐标系<%s>." % (x, y, z, currcsys)
    x, y, z = ypoint
    s6 = "N,ndmax+3,%s,%s,%s," % (x, y, z)
    c6 = "! 新建结点/结点编号<ndmax+3>/结点坐标<(%s,%s,%s)>/坐标系<%s>." % (x, y, z, currcsys)
    cmds = [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6]]
    csystypeypes = {0: "Cartesian", 1: "Cylindrical", 2: "Spherical", }
    if csysnumber is None:
        tmps1 = "*GET,csmax,CDSY,,NUM,MAX"
        tmpc1 = "! 当前最大坐标系参考号<csmax>."
        tmps2 = "*IF,csmax,LE,10,THEN"
        tmpc2 = "! 若当前最大坐标系参考号小于10."
        tmps3 = "    csmax=10"
        tmpc3 = "! 当前最大坐标系参考号取10/用户自定义坐标系参考号需大于10."
        tmps4 = "*ENDIF"
        tmpc4 = "! 结束IF块."
        tmps5 = "CS,csmax+1,%s,ndmax+1,ndmax+2,ndmax+3" % csystype
        tmpc5 = "! 新建坐标系/坐标系参考号<ndmax+1>or<11>/坐标系类型<%s>." % csystypeypes[csystype]
        cmds = cmds + [[tmps1, tmpc1], [tmps2, tmpc2], [tmps3, tmpc3], [tmps4, tmpc4], [tmps5, tmpc5], ]
    else:
        tmps1 = "CS,%s,%s,ndmax+1,ndmax+2,ndmax+3" % (csysnumber, csystype)
        tmpc1 = "! 新建坐标系/坐标系参考号<%s>/坐标系类型<%s>." % (csysnumber, csystype)
        cmds = cmds + [[tmps1, tmpc1],]
    s7 = "NDELE,ndmax+1,ndmax+3,1"
    c7 = "! 删除临时结点/临时结点编号<ndmax+1>、<ndmax+2>和<ndmax+3>."
    s8 = "CSYS,0"
    c8 = "! 激活全局直角坐标系."
    s9 = "ALLSEL,ALL"
    c9 = "! Select Everything."
    cmds = cmds + [[s7, c7], [s8, c8], [s9, c9]]
    return cmds

  例如,我们想创建一编号为 107 的局部柱坐标系,它的坐标原点为 (100, 0, 0),且它的局部 x 轴正方向指向全局 Y 轴正方向,它的局部 y 轴 正方向指向全局 Z 轴负方向。那么,原点坐标参数 origin = [100, 0, 0],局部 x 轴上正方向上一点的坐标可取为 xpoint = [100, 10, 0],局部 xy 平面上且偏向 +y 轴方向的一点坐标可取为 ypoint = [100, 0, -10],基于此,可调用函数 create_coordinate_system_from_three_points 来生成创建 107 号局部柱坐标系的 APDL 命令流,如下所示。


origin, xpoint, ypoint = [100, 0, 0], [100, 10, 0], [100, 0, -10] # 原点/+x轴点/偏+y轴点
csysnumber, csystype, currcsys = 107, 1, 0 # 新建坐标系参考号/新建坐标系类型/当前活跃的坐标系
cmds = create_coordinate_system_from_three_points(origin, xpoint, ypoint, csysnumber, csystype, currcsys)

for var in cmds:
    s, c = var
    cmd = s + " " + c
    print(cmd)

在这里插入图片描述


Python生成的三点创建局部坐标系的APDL命令流


  将生成的 APDL 命令流复制到 ANSYS 经典界面中的命令窗口中,回车后程序执行并创建局部柱坐标系 107,如下图所示。


在这里插入图片描述



  为了节约篇幅,以下各 Python 函数不做具体的测试和太详细的功能说明。




4.3 旋转结点坐标系


  总体和局部坐标系用于几何/网格定位,而结点坐标系则用于定义结点自由度的方向。每个结点都有自己的结点坐标系,默认情况下,它总是平行于总体笛卡尔坐标系 (与定义结点的激活坐标系无关)。在此,我们定义旋转结点坐标的 Python 函数 rotate_nodal_coordinate_system ,用于将系统默认的结点坐标系变更为与给定的坐标系相一致/平行,Python 代码如下:


def rotate_nodal_coordinate_system(nodes=[], targetcsys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:旋转结点坐标系使之与当前激活坐标系相一致(平行)
    # 参数:nodes为结点编号的列表;targetcsys为目标坐标系的参考号
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "CSYS,%s" % targetcsys
    c2 = "! 激活坐标系/坐标系参考号<%s>." % targetcsys
    cmds = [[s1, c1], [s2, c2], ]
    for node in nodes:
        tmps = "NROTAT,%s" % node
        tmpc = "! 旋转结点坐标系/结点编号<%s>/目标坐标系参考号<%s>." % (node, targetcsys)
        cmds.append([tmps, tmpc])
    s3 = "CSYS,0"
    c3 = "! 激活全局直角坐标系."
    cmds.append([s3, c3])
    return cmds
# 示例
# nodes = [1, 107, 88, 97, 23]  # 结点编号
# targetcsys = 102  # 目标坐标系
# cmds = rotate_nodal_coordinate_system(nodes, targetcsys)
# print(cmds)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)


4.4 修改单元坐标系



4.5 激活结果坐标系


  在求解过程中,计算的结果数据有位移 (Ux、Uy、Rots 等),梯度 (Tgx、Tgy 等),应力 (Sx、Sy、Sz 等),应变 (Epplx 、Epplxy 等) 等。这些数据存储在数据库和结果文件中,要么是在结点坐标系 (初始或结点数据),要么是在单元坐标系 (导出或的单元数据)。但是,结果数据通常是旋转到激活的坐标系 (默认为总体笛卡尔坐标系) 中来进行云图显示、列表显示和单元数据存储 (ETABLE 命令) 等操作。


  可以将活动的结果坐标系转换到另一个坐标系 (如总体坐标系或一个局部坐标系),或转换到求解时所用到的坐标系下 (例如结点和单元坐标系)。如果列表、显示或操作这些结果数据,则它们将首先被旋转到结果坐标系下。在此,我们定义改变结果坐标系的 Python 函数 activate_coordinate_system_for_resluts_dispaly,它的详细代码如下:


def activate_coordinate_system_for_resluts_dispaly(csys):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:修改结果坐标系到给定坐标系
    # 参数:csys为目标坐标系的参考号,各计算结果的展示将以该坐标系标定
    # 返回:APDL命令流列表
    s1 = "/POST1"  # 访问通用后处理器
    c1 = "! Enters the database results postprocessor."  # 备注
    s2 = "RSYS,%s" % csys
    c2 = "! 定义结果输出/显示坐标系/坐标系参考号<%s>." % csys
    cmds = [[s1, c1], [s2, c2], ]
    return cmds
# 示例
# csys = 102  # 将坐标系102设置为结果展示坐标系
# cmds = activate_coordinate_system_for_resluts_dispaly(csys)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



4.6 工作平面的定义


  与局部坐标系的定义类似,在日常工作中,采用三点法定义工作平面更为方便,通过给出给定工作平面原点坐标、工作平面 x 轴正方向上一点的坐标和工作平面偏 y 轴正方向上一点的坐标,可唯一定义一工作平面,且工作平面的法线正向可有右手规则确定。


  在此我们可编写名为 define_working_plane_from_three_points 的 Python 函数,用于快速生成由三点法创建工作平面的 ANSYS APDL 命令流,Python 代码如下:


def define_working_plane_from_three_points(origin=[0, 0, 0], xpoint=[1, 0, 0], ypoint=[0, 1, 0], currcsys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由3个点定义一工作平面/工作平面为局部xy平面
    # 参数:origin为工作平面的原点坐标;xpoint为工作平面局部x轴上正方向上一点的坐标;ypoint为工作平面局部xy平面上偏+y方向一点的坐标;
    # 参数:currcsys为当前活跃的坐标系,即上述三个点坐标所参考的坐标系,默认为0(全局直角坐标系)
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "*GET,ndmax,NODE,,NUM,MAX"
    c2 = "! 当前最大结点编号<ndmax>."
    s3 = "CSYS,%s" % currcsys
    c3 = "! 激活坐标系/坐标系参考号<%s>." % currcsys
    x, y, z = origin
    s4 = "N,ndmax+1,%s,%s,%s," % (x, y, z)
    c4 = "! 新建结点/结点编号<ndmax+1>/结点坐标<(%s,%s,%s)>/坐标系<%s>." % (x, y, z, currcsys)
    x, y, z = xpoint
    s5 = "N,ndmax+2,%s,%s,%s," % (x, y, z)
    c5 = "! 新建结点/结点编号<ndmax+2>/结点坐标<(%s,%s,%s)>/坐标系<%s>." % (x, y, z, currcsys)
    x, y, z = ypoint
    s6 = "N,ndmax+3,%s,%s,%s," % (x, y, z)
    c6 = "! 新建结点/结点编号<ndmax+3>/结点坐标<(%s,%s,%s)>/坐标系<%s>." % (x, y, z, currcsys)
    s7 = "NWPLAN,1,ndmax+1,ndmax+2,ndmax+3"
    c7 = "! 定义工作平面/工作平面法线方向由右手规则确定."
    s8 = "NDELE,ndmax+1,ndmax+3,1"
    c8 = "! 删除临时结点/临时结点编号<ndmax+1>、<ndmax+2>和<ndmax+3>."
    s9 = "CSYS,0"
    c9 = "! 激活全局直角坐标系."
    s10 = "ALLSEL,ALL"
    c10 = "! Select Everything."
    cmds = [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9], [s10, c10]]
    return cmds
# 示例
# origin, xpoint, ypoint = [100, 0, 0], [100, 10, 0], [100, 0, -10]
# cmds = define_working_plane_from_three_points(origin, xpoint, ypoint, currcsys=0)
#
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)




五、几何模型



Python函数

序号类别函数名称功能
1几何点create_point(x, y, z, number, csys)创建几何点
2几何线create_line_from_points_coordinates(p1, p2, csys)由起点和终点坐标创建几何线
3几何线create_line_from_points_labels(p1, p2, csys)由起点和终点标签创建几何线
4几何面create_area_from_lines_labels(lines)由组成面的线标签创建几何面
5几何面create_area_from_points_coordinates(points, csys)由组成面的点坐标创建几何面
6几何面create_area_from_points_labels(points)由组成面的点标签创建几何面
7几何体create_solid_from_points_coordinates(points, csys)由组成体的点坐标创建几何体
8几何体create_solid_from_points_labels(points)由组成体的点标签创建几何体
9几何体create_solid_from_areas_labels(areas)由组成体的面标签创建几何体



5.1 创建点和线



5.1.1 由几何点的坐标值创建几何关键点


def create_point(x, y, z, number=None, csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建几何点
    # 参数:x、y和z分别为点的坐标;csys为点所在的坐标系编号;number为创建的点的编号。
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "CSYS,%s" % csys
    c2 = "! 激活坐标系/坐标系参考号<%s>." % csys
    cmds = [[s1, c1], [s2, c2], ]
    if number is None:
        tmps1 = "*GET,kpmax,KP,,NUM,MAX"
        tmpc1 = "! 当前最大关键点编号<kpmax>."
        cmds.append([tmps1, tmpc1])
        number = "kpmax+1"
    s3 = "K,%s,%s,%s,%s" % (number, x, y, z)
    c3 = "! 创建关键点/关键点编号<%s>/关键点坐标<(%s,%s,%s)>/坐标系<%s>." % (number, x, y, z, csys)
    cmds.append([s3, c3])
    return cmds
# 示例
# x, y, z = 10, 20, 10
# cmds = create_point(x, y, z, number=107, csys=0)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



5.1.2 由线的起点和终点坐标创建几何线


def create_line_from_points_coordinates(p1=[], p2=[], csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建几何点
    # 参数:p1和p2分别为线起点和终点的坐标列表;csys为点所在的坐标系
    # 返回:APDL命令流列表
    x1, y1, z1 = p1  # 起点坐标
    x2, y2, z2 = p2  # 终点坐标
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "CSYS,%s" % csys
    c2 = "! 激活坐标系/坐标系参考号<%s>." % csys
    s3 = "*GET,kpmax,KP,,NUM,MAX"
    c3 = "! 当前最大关键点编号<kpmax>."
    number1 = "kpmax+1"  # 起点编号/标签
    s4 = "K,%s,%s,%s,%s" % (number1, x1, y1, z1)
    c4 = "! 创建关键点/关键点编号<%s>/关键点坐标<(%s,%s,%s)>/坐标系<%s>." % (number1, x1, y1, z1, csys)
    number2 = "kpmax+2"  # 终点编号/标签
    s5 = "K,%s,%s,%s,%s" % (number2, x2, y2, z2)
    c5 = "! 创建关键点/关键点编号<%s>/关键点坐标<(%s,%s,%s)>/坐标系<%s>." % (number2, x2, y2, z2, csys)
    s6 = "L,kpmax+1,kpmax+2"
    c6 = "! 创建线/线的起点编号<kpmax+1>/线的终点编号<kpmax+2>."
    cmds = [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6]]
    return cmds
# 示例
# x1, y1, z1 = 0, 0, 0
# x2, y2, z2 = 100, 100, 100
# p1 = [x1, y1, z1]  # 起点坐标
# p2 = [x2, y2, z2]  # 终点坐标
# cmds = create_line_from_points_coordinates(p1, p2, csys=0)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



5.1.3 由线的起点和终点标签创建几何线


def create_line_from_points_labels(p1, p2, csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建几何点
    # 参数:p1和p2分别为线起点和终点的标签;csys为点所在的坐标系(创建的线不一定是直线)
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "CSYS,%s" % csys
    c2 = "! 激活坐标系/坐标系参考号<%s>." % csys
    s3 = "L,%s,%s" % (p1, p2)
    c3 = "! 创建线/线的起点编号<kpmax+1>/线的终点编号<kpmax+2>."
    cmds = [[s1, c1], [s2, c2], [s3, c3]]
    return cmds
# 示例
# p1 = 1  # 起点标签
# p2 = 109  # 终点标签
# cmds = create_line_from_points_labels(p1, p2, csys=0)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



5.2 创建几何面



5.2.1 由组成面的各线的标签创建几何面


def create_area_from_lines_labels(lines=[]):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由线的标签创建几何面,组成面的线必须封闭
    # 参数:lines为线标签的列表
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    linenum = len(lines)  # 线的个数
    s2 = "AL,"
    c2 = "! 创建几何面/组成几何面的线的编号"
    tmps = ""
    if linenum >= 3.0:
        # 至少三条线才能创建面
        for line in lines:
            tmps = tmps + "%s," % line
    tmps = tmps[:-1]
    s2 = s2 + tmps
    c2 = c2 + "<%s>." % tmps
    cmds = [[s1, c1], [s2, c2], ]
    return cmds


create_area_from_lines = create_area_from_lines_labels
# 示例
# lines = [1,3,4]
# cmds = create_area_from_lines_labels(lines)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



5.2.2 由组成面的各点的坐标创建几何面


def create_area_from_points_coordinates(points=[], csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由组成面的各点坐标创建几何面
    # 参数:points为组成面的各点的坐标列表,点坐标的排序需满足顺逆时针要求;csys为点所在的坐标系
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    pointnum = len(points)  # 点的个数
    if pointnum >= 3.0:
        s2 = "CSYS,%s" % csys
        c2 = "! 激活坐标系/坐标系参考号<%s>." % csys
        s3 = "*GET,kpmax,KP,,NUM,MAX"
        c3 = "! 当前最大关键点编号<kpmax>."
        cmds = [[s1, c1], [s2, c2], [s3, c3], ]
        tmps1 = ""
        for i, point in enumerate(points):
            x, y, z = point
            number = "kpmax+%s" % (i + 1)
            tmps2 = "K,%s,%s,%s,%s" % (number, x, y, z)
            tmpc2 = "! 创建关键点/关键点编号<%s>/关键点坐标<(%s,%s,%s)>/坐标系<%s>." % (number, x, y, z, csys)
            cmds.append([tmps2, tmpc2])
            tmps1 = tmps1 + "%s," % number
        s4 = "A," + tmps1[:-1]
        c4 = "! 创建几何面/组成面的各点编号<kpmax+1~kpmax+%s>." % pointnum
        cmds.append([s4, c4])
        return cmds
# 示例
# x1, y1, z1 = 0, 0, 0
# x2, y2, z2 = 100, 100, 0
# x3, y3, z3 = 200, 0, 0
# p1 = [x1, y1, z1]
# p2 = [x2, y2, z2]
# p3 = [x3, y3, z3]
# points = [p1, p2, p3]
# cmds = create_area_from_points_coordinates(points, csys=0)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)

在这里插入图片描述


示例代码的运行结果




5.2.3 由组成面的各点的标签创建几何面


def create_area_from_points_labels(points=[]):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由组成面的各点标签创建几何面
    # 参数:points为组成面的各点的标签列表,点标签的排序需满足顺逆时针要求
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    pointnum = len(points)  # 点的个数
    if pointnum >= 3.0:
        s2 = "A,"
        c2 = ""
        for point in points:
            s2 = s2 + "%s," % point
            c2 = c2 + "%s," % point
        s2 = s2[:-1]
        c2 = "! 创建几何面/组成面的各点编号<%s>." % c2[:-1]
        cmds = [[s1, c1], [s2, c2]]
        return cmds
# 示例
# points = [1,2,3] # 几何点标签列表
# cmds = create_area_from_points_labels(points)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)





5.3 创建几何体



5.3.1 由组成体的各点的坐标创建几何体


def create_solid_from_points_coordinates(points=[], csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由组成几何体的各点坐标创建几何体
    # 参数:points为组成几何体的各点的坐标列表;csys为各点所在的坐标系
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    pointnum = len(points)  # 点的个数
    if pointnum >= 4.0:
        s2 = "CSYS,%s" % csys
        c2 = "! 激活坐标系/坐标系参考号<%s>." % csys
        s3 = "*GET,kpmax,KP,,NUM,MAX"
        c3 = "! 当前最大关键点编号<kpmax>."
        cmds = [[s1, c1], [s2, c2], [s3, c3], ]
        tmps1 = ""
        for i, point in enumerate(points):
            x, y, z = point
            number = "kpmax+%s" % (i + 1)
            tmps2 = "K,%s,%s,%s,%s" % (number, x, y, z)
            tmpc2 = "! 创建关键点/关键点编号<%s>/关键点坐标<(%s,%s,%s)>/坐标系<%s>." % (number, x, y, z, csys)
            cmds.append([tmps2, tmpc2])
            tmps1 = tmps1 + "%s," % number
        s4 = "V," + tmps1[:-1]
        c4 = "! 创建几何体/组成体的各点编号<kpmax+1~kpmax+%s>." % pointnum
        cmds.append([s4, c4])
        return cmds
create_volume_from_points_coordinates = create_solid_from_points_coordinates
# 示例
# x1, y1, z1 = -100, 0, 0
# x2, y2, z2 = 100, 0, 0
# x3, y3, z3 = 0, 100, 0
# x4, y4, z4 = 50, 50, 100
# p1 = [x1, y1, z1]
# p2 = [x2, y2, z2]
# p3 = [x3, y3, z3]
# p4 = [x4, y4, z4]
# points = [p1, p2, p3, p4]
# cmds = create_solid_from_points_coordinates(points, csys=0)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)




5.3.2 由组成体的各点的标签创建几何体


def create_solid_from_points_labels(points=[]):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由组成几何体的各点标签创建几何体
    # 参数:points为组成几何体的各点的标签列表
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    pointnum = len(points)  # 点的个数
    if pointnum >= 4.0:
        s2 = "V,"
        c2 = ""
        for point in points:
            s2 = s2 + "%s," % point
            c2 = c2 + "%s," % point
        s2 = s2[:-1]
        c2 = "! 创建几何面/组成面的各点编号<%s>." % c2[:-1]
        cmds = [[s1, c1], [s2, c2]]
        return cmds
create_volume_from_points_labels = create_solid_from_points_labels
# 示例
# points = [4, 5, 6, 7]  # 几何点标签列表
# cmds = create_solid_from_points_labels(points)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



5.3.3 由组成体的各线的标签创建几何体




5.3.4 由组成体的各面的标签创建几何体


def create_solid_from_areas_labels(areas=[]):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:由组成几何体的各面的标签创建几何体
    # 参数:areas为组成几何体的各面的标签列表
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    areasnum = len(areas)  # 点的个数
    if areasnum >= 3.0:
        s2 = "VA,"
        c2 = ""
        for area in areas:
            s2 = s2 + "%s," % area
            c2 = c2 + "%s," % area
        s2 = s2[:-1]
        c2 = "! 创建几何体/组成体的各面编号<%s>." % c2[:-1]
        cmds = [[s1, c1], [s2, c2]]
        return cmds
create_solid_from_areas = create_solid_from_areas_labels
# 示例
# areas = [2, 3, 4, 5]  # 几何点标签列表
# cmds = create_solid_from_areas_labels(areas)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)



5.3.5 由几何平面的拉伸创建几何拉伸体











六、网格划分



6.1 设置种子数目


def set_seeds_for_lines(compname=None, lines=[], size=None, number=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:通过指定网格尺寸/数目布设全局种子
    # 参数:compname为组件名称;lines为线的编号列表
    # 参数:size为全局网格尺寸大小;number为全局网格的数目/每条边的网格数目
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    cmds = [[s1, c1], [s2, c2]]
    if compname is not None:
        tmps = "CMSEL,S,%s" % compname
        tmpc = "! 选择组件/组件名称<%s>." % compname
        cmds.append([tmps, tmpc])
        tmps = "LSEL,R,LINE,,ALL"
        tmpc = "! 补充筛选条件/选择全部线对象."
        cmds.append([tmps, tmpc])
    if len(lines) > 0.0:
        line = lines[0]
        tmps = "LSEL,S,LINE,,%s" % line
        tmpc = "! 新建选择集/选择线/线的编号<%s>." % line
        cmds.append([tmps, tmpc])
        for line in lines[1:]:
            tmps = "LSEL,A,LINE,,%s" % line
            tmpc = "! 补充选择集/选择线/线的编号<%s>." % line
            cmds.append([tmps, tmpc])
    if compname is None and len(lines) < 1.0:
        tmps = "LSEL,S,LINE, ,ALL"
        tmpc = "! 新建选择集/选择全部线对象."
        cmds.append([tmps, tmpc])
    if size is not None:
        tmps = "LESIZE,ALL,%s,,,,1,,,1" % size
        tmpc = "! 布设种子/网格尺寸<%s>." % size
        cmds.append([tmps, tmpc])
    if number is not None:
        tmps = "LESIZE,ALL,,,%s,,1,,,1" % number
        tmpc = "! 布设种子/网格数目<%s>." % number
        cmds.append([tmps, tmpc])
    cmds.append([s2, c2])
    return cmds




6.2 执行网格划分


def create_mesh(areas=[], solids=[], shape=0, technique="Free", etnum=1):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建网格
    # 参数:areas为面的标签列表;solids为体的标签列表;二者不能同时指定。
    # 参数:shape为形状控制选项,dimension为网格的维度,可以为2D或3D
    # 参数:shape=0表示二维四边形、三维六面体
    # 参数:shape=1表示二维三角形、三维四面体
    # 参数:technique为网格划分技术,可以为自由分网(Free)和映射分网(Mapped)。
    # 参数:etnum为生成网格所采用的单元类型号
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    cmds = [[s1, c1], [s2, c2], ]
    shapeDic = {"2D": {0: "四边形", 1: "三角形"},
                "3D": {0: "六面体", 1: "四面体"}}
    techniqueDic = {"Free": ["自由分网", 0], "Mapped": ["映射分网", 1], }  # 分网技术
    if len(areas) > 0 and len(solids) == 0.0:
        # 为几何面对象划分网格
        area = areas[0]
        tmps = "ASEL,S,AREA,,%s" % area
        tmpc = "! 新建选择集/选择面/面的编号<%s>." % area
        cmds.append([tmps, tmpc])
        for area in areas[1:]:
            tmps = "ASEL,A,AREA,,%s" % area
            tmpc = "! 补充选择集/选择面/面的编号<%s>." % area
            cmds.append([tmps, tmpc])
        tmps1 = "MSHAPE,%s,2D" % shape
        tmpc1 = "! 定义网格形状/面网格/网格形状<%s>." % shapeDic["2D"][shape]
        tmps2 = "MSHKEY,%s" % techniqueDic[technique][1]
        tmpc2 = "! 设置网格划分技术/网格划分采用<%s>技术." % techniqueDic[technique][0]
        tmps3 = "TYPE,%s" % etnum
        tmpc3 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        tmps4 = "AMESH,ALL"
        tmpc4 = "! 划分面网格."
        cmds = cmds + [[tmps1, tmpc1], [tmps2, tmpc2], [tmps3, tmpc3], [tmps4, tmpc4], ]
    if len(solids) > 0 and len(areas) == 0.0:
        # 为几何体对象划分网格
        solid = solids[0]
        tmps = "VSEL,S,VOLU,,%s" % solid
        tmpc = "! 新建选择集/选择体/体的编号<%s>." % solid
        cmds.append([tmps, tmpc])
        for solid in solids[1:]:
            tmps = "VSEL,A,VOLU,,%s" % solid
            tmpc = "! 补充选择集/选择体/体的编号<%s>." % solid
            cmds.append([tmps, tmpc])
        tmps1 = "MSHAPE,%s,3D" % shape
        tmpc1 = "! 定义网格形状/体网格/网格形状<%s>." % shapeDic["3D"][shape]
        tmps2 = "MSHKEY,%s" % techniqueDic[technique][1]
        tmpc2 = "! 设置网格划分技术/网格划分采用<%s>技术." % techniqueDic[technique][0]
        tmps3 = "TYPE,%s" % etnum
        tmpc3 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        tmps4 = "VMESH,ALL"
        tmpc4 = "! 划分体网格."
        cmds = cmds + [[tmps1, tmpc1], [tmps2, tmpc2], [tmps3, tmpc3], [tmps4, tmpc4]]
    return cmds





七、有限元模型


7.1 创建网格结点


def create_node(x, y, z, number=None, csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建有限元结点
    # 参数:x、y和z分别为结点的坐标;csys为结点所在的坐标系编号;number为创建的结点的编号。
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "CSYS,%s" % csys
    c2 = "! 激活坐标系/坐标系参考号<%s>." % csys
    cmds = [[s1, c1], [s2, c2], ]
    if number is None:
        tmps1 = "*GET,ndmax,NODE,,NUM,MAX"
        tmpc1 = "! 当前最大结点编号<ndmax>."
        cmds.append([tmps1, tmpc1])
        number = "ndmax+1"
    s3 = "N,%s,%s,%s,%s" % (number, x, y, z)
    c3 = "! 创建结点/结点编号<%s>/结点坐标<(%s,%s,%s)>/坐标系<%s>." % (number, x, y, z, csys)
    cmds.append([s3, c3])
    return cmds
# 示例
# x, y, z = 150, 0, 150
# cmds = create_node(x, y, z, number=102, csys=0)
# for var in cmds:
#     s, c = var
#     cmd = s + " " + c
#     print(cmd)


7.2 创建〇维单元


在这里插入图片描述


MASS21单元


def create_mass_element_on_node(node=1, massx=0, massy=0, massz=0, ixx=0, iyy=0, izz=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:创建质量点。
    # 参数:node为结点编号
    # 参数:MASSX, MASSY, MASSZ, IXX, IYY, IZZ为六个方向上的结点质量,采用结点坐标系标定。
    # 返回:APDL命令流列表。
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "*GET,etmax,ETYP,,NUM,MAX"
    c3 = "! 当前最大单元类型编号<etmax>."
    s4 = "*GET,rlmax,RCON,,NUM,MAX"
    c4 = "! 当前最大实常数编号<rlmax>."
    s5 = "ET,etmax+1,MASS21"
    c5 = "! 定义质量单元."
    s6 = "KEYOPT,etmax+1,1,0"
    c6 = "! KEYOPT(1)=0/实常数中的数据以质量和转动惯量形式施加/系统默认."
    s7 = "KEYOPT,etmax+1,2,1"
    c7 = "! KEYOPT(2)=1/坐标系采用结点坐标系标定."
    s8 = "KEYOPT,etmax+1,3,0"
    c8 = "! KEYOPT(3)=0/3-D mass with rotary inertia/质点具有6个自由度/系统默认."
    s9 = "R,rlmax+1,%s,%s,%s,%s,%s,%s" % (massx, massy, massz, ixx, iyy, izz)
    c9 = "! 定义实常数/质点属性<%s,%s,%s,%s,%s,%s>." % (massx, massy, massz, ixx, iyy, izz)
    cmds = [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9], ]
    s1 = "TYPE,etmax+1"
    c1 = "! 激活单元类型/单元类型编号<etmax+1>."
    s2 = "REAL,rlmax+1"
    c2 = "! 激活实常数/实常数编号<etmax+1>."
    s3 = "E,%s" % node
    c3 = "! 创建质量单元/单元所在结点编号<%s>." % node
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], ]
    return cmds



7.3 创建一维单元


在这里插入图片描述


BEAM188和BEAM189单元


def create_1d_2node_beam_element(nodes=[], etnum=188, secnum=None, matnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:创建一维2结点梁单元,BEAM188。
    # 参数:nodes为构成单元所必须的结点标签列表,其内有三个元素,依次为n1,n2,n3。
    # 参数:n1、n2分别为单元起点和终点编号;n3为梁截面局部轴的定位点。
    # 参数:etnum为梁单元的单元类型号,必须给定,默认为188;secnum为梁的截面编号;matnum为所采用的材料编号。
    # 返回:APDL命令流列表
    if len(nodes) == 3.0:
        n1, n2, n3 = nodes
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        cmds = [[s1, c1], [s2, c2], ]
        if etnum == 188:
            s3 = "ET,188,BEAM188"
            c3 = "! 定义默认单元类型(防报错用)/单元类型编号<188>/单元类别名称<BEAM188>."
            cmds.append([s3, c3])
        s4 = "TYPE,%s" % etnum
        c4 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        cmds.append([s4, c4])
        if matnum is not None:
            s5 = "MAT,%s" % matnum
            c5 = "! 激活材料编号/材料编号<%s>." % matnum
            cmds.append([s5, c5])
        if secnum is not None:
            s6 = "SECNUM,%s" % secnum
            c6 = "! 激活截面编号/截面编号<%s>." % secnum
            cmds.append([s6, c6])
        s7 = "E,%s,%s,%s," % (n1, n2, n3)  # 创建梁单元
        c7 = "! 创建一阶梁单元/起点编号<%s>/终点编号<%s>/方向点编号<%s>." % (n1, n2, n3)  # 起点/终点/方向点
        cmds = cmds + [[s7, c7], ]
        return cmds


def create_1d_3node_beam_element(nodes=[], etnum=189, secnum=None, matnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建一维3结点梁单元,BEAM189。
    # 参数:nodes为构成单元所必须的结点标签列表,其内有四个元素,依次为n1,n2,n3,n4。
    # 参数:n1、n2分别为单元起点和终点编号;n3为梁的中点编号;n4为梁截面局部轴的定位点。
    # 参数:etnum为梁单元的单元类型号,必须给定,默认值189;secnum为梁的截面编号;matnum为所采用的材料编号。
    # 返回:APDL命令流列表
    if len(nodes) == 4.0:
        n1, n2, n3, n4 = nodes
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        cmds = [[s1, c1], [s2, c2], ]
        if etnum == 189:
            s3 = "ET,189,BEAM189"
            c3 = "! 定义默认单元类型(防报错用)/单元类型编号<189>/单元类别名称<BEAM189>."
            cmds.append([s3, c3])
        s4 = "TYPE,%s" % etnum
        c4 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        cmds.append([s4, c4])
        if matnum is not None:
            s5 = "MAT,%s" % matnum
            c5 = "! 激活材料编号/材料编号<%s>." % matnum
            cmds.append([s5, c5])
        if secnum is not None:
            s6 = "SECNUM,%s" % secnum
            c6 = "! 激活截面编号/截面编号<%s>." % secnum
            cmds.append([s6, c6])
        s7 = "E,%s,%s,%s,%s" % (n1, n2, n3, n4)  # 创建梁单元
        c7 = "! 创建二阶梁单元/起点编号<%s>/终点编号<%s>/中点编号<%s>/方向点编号<%s>." % (n1, n2, n3, n4)  # 起点/终点/中点/方向点
        cmds = cmds + [[s7, c7], ]
        return cmds


def create_1d_3node_cable_element(n1, n2, n3, n4, etnum, secnum=None, matnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建一维3结点索单元,CABLE280
    # 返回:APDL命令流列表
    pass




7.4 创建二维单元


在这里插入图片描述


SHELL181单元


def create_2d_4node_structural_shell_element(n1, n2, n3, n4=None, etnum=181, secnum=None, matnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建二维空间4结点结构壳单元,SHELL181,可退化为三角形单元。
    # 参数:nodes为构成单元所必须的结点标签列表,其内有四个元素,依次为n1,n2,n3,n4。
    # 参数:n1、n2、n3和n4分别为组成壳单元的四个结点编号,需逆时针排列,当n4不给定时,单元退化为三角形单元。
    # 参数:etnum为梁单元的单元类型号,必须给定,默认值181;secnum为梁的截面编号;matnum为所采用的材料编号。
    # 返回:APDL命令流列表
    if len(nodes) == 4.0:
        n1, n2, n3, n4 = nodes
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        cmds = [[s1, c1], [s2, c2], ]
        if etnum == 181:
            s3 = "ET,181,SHELL181"
            c3 = "! 定义默认单元类型(防报错用)/单元类型编号<181>/单元类别名称<SHELL181>."
            cmds.append([s3, c3])
        s4 = "TYPE,%s" % etnum
        c4 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        cmds.append([s4, c4])
        if matnum is not None:
            s5 = "MAT,%s" % matnum
            c5 = "! 激活材料编号/材料编号<%s>." % matnum
            cmds.append([s5, c5])
        if secnum is not None:
            s6 = "SECNUM,%s" % secnum
            c6 = "! 激活截面编号/截面编号<%s>." % secnum
            cmds.append([s6, c6])
        shape = "四边形"
        if n3 == n4:
            shape = "三角形"
        s7 = "E,%s,%s,%s,%s" % (n1, n2, n3, n4)  # 创建壳单元
        c7 = "! 创建一阶四结点壳单元/单元形状<%s>/单元结点编号序列<%s,%s,%s,%s>." % (shape, n1, n2, n3, n4)
        cmds = cmds + [[s7, c7], ]
        return cmds



7.5 创建三维单元



在这里插入图片描述


SOLID187单元


def create_3d_10node_structural_solid_element(nodes=[], etnum=187, secnum=None, matnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:创建三维空间10结点四面体结构单元,SOLID187。
    # 参数:nodes为组成二阶四面体单元的10个结点编号列表,顺序排列。
    # 参数:etnum为梁单元的单元类型号,必须给定,默认值为187;secnum为梁的截面编号;matnum为所采用的材料编号。
    # 返回:APDL命令流列表
    if len(nodes) == 10.0:
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        cmds = [[s1, c1], [s2, c2], ]
        if etnum == 187:
            s3 = "ET,187,SOLID187"
            c3 = "! 定义默认单元类型(防报错用)/单元类型编号<187>/单元类别名称<SOLID187>."
            cmds.append([s3, c3])
        s4 = "TYPE,%s" % etnum
        c4 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        cmds.append([s4, c4])
        if matnum is not None:
            s5 = "MAT,%s" % matnum
            c5 = "! 激活材料编号/材料编号<%s>." % matnum
            cmds.append([s5, c5])
        if secnum is not None:
            s6 = "SECNUM,%s" % secnum
            c6 = "! 激活截面编号/截面编号<%s>." % secnum
            cmds.append([s6, c6])
        s7 = "E,"
        for node in nodes:
            s7 = s7 + "%s," % node
        s7 = s7[:-1]
        c7 = "! 创建二阶10结点四面体单元/单元结点编号序列<%s>." % s7[2:]
        cmds = cmds + [[s7, c7], ]
        return cmds



在这里插入图片描述


SOLID185单元


def create_3d_8node_structural_solid_element(nodes=[], etnum=185, secnum=None, matnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:创建三维空间8结点六面体单元,SOLID185,它可以退化为四面体或五面体单元
    # 参数:nodes为组成一阶六面体单元的8个结点编号列表,顺序排列。
    # 参数:etnum为梁单元的单元类型号,必须给定,默认值为185;secnum为梁的截面编号;matnum为所采用的材料编号。
    # 返回:APDL命令流列表
    if len(nodes) == 8:
        n1, n2, n3, n4, n5, n6, n7, n8 = nodes
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        cmds = [[s1, c1], [s2, c2], ]
        if etnum == 185:
            s3 = "ET,185,SOLID185"
            c3 = "! 定义默认单元类型(防报错用)/单元类型编号<185>/单元类别名称<SOLID185>."
            cmds.append([s3, c3])
        s4 = "TYPE,%s" % etnum
        c4 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        cmds.append([s4, c4])
        if matnum is not None:
            s5 = "MAT,%s" % matnum
            c5 = "! 激活材料编号/材料编号<%s>." % matnum
            cmds.append([s5, c5])
        if secnum is not None:
            s6 = "SECNUM,%s" % secnum
            c6 = "! 激活截面编号/截面编号<%s>." % secnum
            cmds.append([s6, c6])
        shape = "标准六面体"
        if n3 == n4 and n7 == n8:
            n4, n8 = n3, n7
            shape = "退化五面棱柱体"
        tmpnodes = [n5, n6, n7, n8]
        if len(list(set(tmpnodes))) == 1.0:
            n6, n7, n8 = n5, n5, n5
            shape = "退化五面棱锥体"
        if len(list(set(tmpnodes))) == 1.0 and n3 == n4:
            n4, n6, n7, n8 = n3, n5, n5, n5
            shape = "退化标准四面体"
        nodes = [n1, n2, n3, n4, n5, n6, n7, n8]
        s7 = "E,"
        for node in nodes:
            s7 = s7 + "%s," % node
        s7 = s7[:-1]
        c7 = "! 创建一阶8结点六面体单元/单元形状<%s>/单元结点编号序列<%s>." % (shape, s7[2:])
        cmds = cmds + [[s7, c7], ]
        return cmds



在这里插入图片描述


SOLID186单元


def create_3d_20node_structural_solid_element(nodes=[], etnum=186, secnum=None, matnum=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:创建三维空间20结点六面体单元,SOLID186,它可以退化为四面体或五面体单元
    # 参数:nodes为组成二阶六面体单元的20个结点编号列表,顺序排列。
    # 参数:etnum为梁单元的单元类型号,必须给定;secnum为梁的截面编号;matnum为所采用的材料编号。
    # 返回:APDL命令流列表
    if len(nodes) == 20:
        n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20 = nodes
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        cmds = [[s1, c1], [s2, c2], ]
        if etnum == 186:
            s3 = "ET,186,SOLID186"
            c3 = "! 定义默认单元类型(防报错用)/单元类型编号<186>/单元类别名称<SOLID186>."
            cmds.append([s3, c3])
        s4 = "TYPE,%s" % etnum
        c4 = "! 激活单元类型编号/单元类型编号<%s>." % etnum
        cmds.append([s4, c4])
        if matnum is not None:
            s5 = "MAT,%s" % matnum
            c5 = "! 激活材料编号/材料编号<%s>." % matnum
            cmds.append([s5, c5])
        if secnum is not None:
            s6 = "SECNUM,%s" % secnum
            c6 = "! 激活截面编号/截面编号<%s>." % secnum
            cmds.append([s6, c6])
        shape = "标准六面体"
        tmp1nodes = [n3, n4, n11, ]
        tmp2nodes = [n19, n20, ]
        tmp3nodes = [n7, n8, n15, ]
        tmp4nodes = [n5, n6, n7, n8, n13, n14, n15, n16, ]
        num1 = len(list(set(tmp1nodes)))
        num2 = len(list(set(tmp2nodes)))
        num3 = len(list(set(tmp3nodes)))
        num4 = len(list(set(tmp4nodes)))
        if num1 == 1.0 and num2 == 1.0 and num3 == 1.0 and num4 > 1.0:
            n4, n11 = n3, n3
            n20 = n19
            n8, n15 = n7, n7
            shape = "退化五面棱柱体"
        if num1 > 1.0 and num2 > 1.0 and num3 > 1.0 and num4 == 1.0:
            n6, n7, n8, n13, n14, n15, n16 = n5, n5, n5, n5, n5, n5, n5
            shape = "退化五面棱锥体"
        if num1 == 1.0 and num2 == 1.0 and num3 == 1.0 and num4 == 1.0:
            n4, n11 = n3, n3
            n20 = n19
            n6, n7, n8, n13, n14, n15, n16 = n5, n5, n5, n5, n5, n5, n5
            shape = "退化标准四面体"
        nodes = [n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20]
        tmps = ""
        for node in nodes:
            tmps = tmps + "%s," % node
        tmps = tmps[:-1]
        s7 = "E," + tmps[:15]
        c7 = "! 创建二阶20结点六面体单元/单元形状<%s>/单元1~8结点编号序列<%s>." % (shape, tmps[:15])
        s8 = "EMORE," + tmps[16:35]
        c8 = "! 创建二阶20结点六面体单元/单元形状<%s>/单元9~16结点编号序列<%s>." % (shape, tmps[16:35])
        s9 = "EMORE," + tmps[36:]
        c9 = "! 创建二阶20结点六面体单元/单元形状<%s>/单元17~20结点编号序列<%s>." % (shape, tmps[36:])
        cmds = cmds + [[s7, c7], [s8, c8], [s9, c9], ]
        return cmds




八、组件与集合


8.1 组件


  在 HyperMesh/ANSYS 中,采用组件 Component 的形式对模型进行组织管理,而 ABAQUS 中采用 部件 Part 的形式对模型进行组织管理。在 ANSYS 中,通常将零件的有限元模型以 .cdb 的方式存储,所有零件创建完成后再统一装配。


  在 ANSYS 中,Component 可以是单元、可以是几何、亦可以是结点。而 Abaqus 中区分 Part 和 Set 。Component 可以为大集合类。


def create_component(cname):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建组件/组件包含的实体类型为单元
    # 参数:cname为组件名称
    # 返回:APDL命令流列表
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL,ELEM"
    c2 = "! Selects all elements."
    s3 = "CM,%s,ELEM" % cname
    c3 = "! 创建组件/组件名称<%s>/组件类型为单元." % cname
    cmds = [[s1, c1], [s2, c2], [s3, c3]]
    return cmds
# 示例
# cname = "TopFlange"
# cmds = create_component(cname)
# print(cmds)



8.2 集合


8.2.1 创建结点集合


def create_node_set_from_labels(compname, nodes=[]):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:由结点标签创建结点集合/组件
    # 参数:compname为组件/集合的名称
    # 参数:nodes为结点标签序列列表
    # 返回:APDL命令流列表
    if len(nodes) > 0.0:
        nodes = list(set(nodes))
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        node = nodes[0]
        s3 = "NSEL,S,NODE,,%s" % node
        c3 = "! 新建选择集/选择结点/结点的编号<%s>." % node
        cmds = [[s1, c1], [s2, c2], [s3, c3], ]
        for node in nodes[1:]:
            s4 = "NSEL,A,NODE,,%s" % node
            c4 = "! 补充选择集/选择结点/结点的编号<%s>." % node
            cmds.append([s4, c4])
        s5 = "CM,%s,NODE" % compname
        c5 = "! 创建组件/组件类型<结点>/组件名称<%s>." % compname
        cmds.append([s5, c5])
        cmds.append([s2, c2])
        return cmds



8.2.2 创建单元集合


def create_element_set_from_labels(compname, elements=[]):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:由单元标签创建单元集合/组件
    # 参数:compname为组件/集合的名称
    # 参数:elements为单元标签序列列表
    # 返回:APDL命令流列表
    if len(elements) > 0.0:
        elements = list(set(elements))
        s1 = "/PREP7"  # 命令
        c1 = "! Enters the model creation preprocessor."  # 备注
        s2 = "ALLSEL,ALL"
        c2 = "! Select Everything."
        elem = elements[0]
        s3 = "ESEL,S,ELEM,,%s" % elem
        c3 = "! 新建选择集/选择单元/单元的编号<%s>." % elem
        cmds = [[s1, c1], [s2, c2], [s3, c3], ]
        for elem in elements[1:]:
            s4 = "ESEL,A,ELEM,,%s" % elem
            c4 = "! 补充选择集/选择单元/单元的编号<%s>." % elem
            cmds.append([s4, c4])
        s5 = "CM,%s,ELEM" % compname
        c5 = "! 创建组件/组件类型<单元>/组件名称<%s>." % compname
        cmds.append([s5, c5])
        cmds.append([s2, c2])
        return cmds




九、接触与约束


  ANSYS 支持三种接触方式:点-点点-面面-面 接触,每种接触方式使用的接触单元适用于某类问题。


  为了给接触问题建模,首先必须认识到模型中的哪些部分可能会相互接触,如果相互作用的其中之一是一点,模型的对立应组元是一个结点。如果相互作用的其中之一是一个面,模型的对应组元是单元,例如梁单元,壳单元或实体单元,有限元模型通过指定的接触单元来识别可能的接触匹对,接触单元是覆盖在分析模型接触面之上的一层单元。


在这里插入图片描述




9.1 创建面-面绑定约束


def create_tie_constraint(master, slave):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:创建面面绑定约束
    # 参数:master为主面结点集合的名称;slave为从面结点集合的名称。
    # 返回:APDL命令流。
    cmds = []
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "*GET,etmax,ETYP,,NUM,MAX"
    c3 = "! 当前最大单元类型编号<etmax>."
    s4 = "*GET,rlmax,RCON,,NUM,MAX"
    c4 = "! 当前最大实常数编号<rlmax>."
    s5 = "R,rlmax+1"
    c5 = "! 定义实常数/实常数编号<rlmax+1>."
    s6 = "REAL,rlmax+1"
    c6 = "! 激活实常数/实常数编号<rlmax+1>."
    s7 = "ET,etmax+1,TARGE170"
    c7 = "! 定义目标面单元/连续面/单元编号<etmax+1>."
    s8 = "ET,etmax+2,CONTA174"
    c8 = "! 定义接触面单元/离散面/单元编号<etmax+2>."
    s9 = "KEYOPT,etmax+2,2,2"
    c9 = "! 设置单元关键项/KEYOPT(2)=2."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    s1 = "KEYOPT,etmax+2,4,1"
    c1 = "! 设置单元关键项/KEYOPT(4)=1."
    s2 = "KEYOPT,etmax+2,5,3"
    c2 = "! 设置单元关键项/KEYOPT(5)=3."
    s3 = "KEYOPT,etmax+2,9,1"
    c3 = "! 设置单元关键项/KEYOPT(9)=1."
    s4 = "KEYOPT,etmax+2,10,2"
    c4 = "! 设置单元关键项/KEYOPT(10)=2."
    s5 = "KEYOPT,etmax+2,12,5"
    c5 = "! 设置单元关键项/KEYOPT(12)=5."
    s6 = "ALLSEL,ALL"
    c6 = "! Select Everything."
    s7 = "CMSEL,S,%s" % master
    c7 = "! 选择主面组件/结点集<%s>." % master
    s8 = "TYPE,etmax+1"
    c8 = "! 激活目标单元类型号<etmax+1>."
    s9 = "ESURF,"
    c9 = "! 创建上覆表面单元/TARGET170."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    s1 = "ALLSEL,ALL"
    c1 = "! Select Everything."
    s2 = "CMSEL,S,%s" % slave
    c2 = "! 选择从面组件/结点集<%s>." % slave
    s3 = "TYPE,etmax+2"
    c3 = "! 激活接触单元类型号<etmax+2>."
    s4 = "ESURF,"
    c4 = "! 创建上覆表面单元/CONTACT174."
    s5 = "ALLSEL,ALL"
    c5 = "! Select Everything."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5]]
    return cmds



9.2 创建面-面标准接触


def create_standard_contact(master, slave, mu, pinball="<auto>", offset=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn。
    # 功能:创建面面标准接触
    # 参数:master为主面结点集合的名称;slave为从面结点集合的名称。
    # 参数:mu为接触面摩擦系数;pinball默认为自动,可以设置任意阿拉伯数字。
    # 参数:offset为初始偏置-间隙/过盈。
    # 返回:APDL命令流。
    cmds = []
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "*GET,etmax,ETYP,,NUM,MAX"
    c3 = "! 当前最大单元类型编号<etmax>."
    s4 = "*GET,rlmax,RCON,,NUM,MAX"
    c4 = "! 当前最大实常数编号<rlmax>."
    s5 = "R,rlmax+1"
    c5 = "! 定义实常数/实常数编号<rlmax+1>."
    s6 = "*GET,matmax,ETYP,,NUM,MAX"
    c6 = "! 当前最大材料编号<matmax>."
    s7 = "MP,MU,matmax+1,%s" % mu
    c7 = "! 定义材料属性/摩擦系数/mu=<%s>." % mu
    s8 = "MAT,matmax+1"
    c8 = "! 激活材料编号<matmax+1>."
    s9 = "R,rlmax+1"
    c9 = "! 定义实常数/实常数编号<rlmax+1>."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    if pinball != "<auto>":
        s1 = "R,rlmax+1,,,,,,%s," % pinball
        c1 = "! 定义实常数/实常数编号<rlmax+1>/Pinball=<%s>." % pinball
        cmds.append([s1, c1])
    if offset != 0.0:
        s2 = "RMORE,,,,%s,," % offset
        c2 = "! 定义接触面偏置/offset=<%s>." % offset
        cmds.append([s2, c2])
    s3 = "REAL,rlmax+1"
    c3 = "! 激活实常数/实常数编号<rlmax+1>."
    s4 = "ET,etmax+1,TARGE170"
    c4 = "! 定义目标面单元/连续面/单元编号<etmax+1>."
    s5 = "ET,etmax+2,CONTA174"
    c5 = "! 定义接触面单元/离散面/单元编号<etmax+2>."
    cmds = cmds + [[s3, c3], [s4, c4], [s5, c5], ]
    if offset > 0.0:
        # 过盈
        s6 = "KEYOPT,etmax+2,5,0"
        c6 = "! 设置单元关键项/KEYOPT(5)=0."
        s7 = "KEYOPT,etmax+2,9,4"
        c7 = "! 设置单元关键项/KEYOPT(9)=4."
        s8 = "KEYOPT,etmax+2,10,2"
        c8 = "! 设置单元关键项/KEYOPT(10)=2."
        cmds = cmds + [[s6, c6], [s7, c7], [s8, c8], ]
    if offset < 0.0:
        # 间隙
        s6 = "KEYOPT,etmax+2,5,0"
        c6 = "! 设置单元关键项/KEYOPT(5)=0."
        s7 = "KEYOPT,etmax+2,9,4"
        c7 = "! 设置单元关键项/KEYOPT(9)=4."
        s8 = "KEYOPT,etmax+2,10,2"
        c8 = "! 设置单元关键项/KEYOPT(10)=2."
        cmds = cmds + [[s6, c6], [s7, c7], [s8, c8], ]
    if offset == 0.0:
        # 标准
        s6 = "KEYOPT,etmax+2,5,4"
        c6 = "! 设置单元关键项/KEYOPT(5)=4."
        s7 = "KEYOPT,etmax+2,9,1"
        c7 = "! 设置单元关键项/KEYOPT(9)=1."
        s8 = "KEYOPT,etmax+2,10,2"
        c8 = "! 设置单元关键项/KEYOPT(10)=2."
        cmds = cmds + [[s6, c6], [s7, c7], [s8, c8], ]
    s9 = "ALLSEL,ALL"
    c9 = "! Select Everything."
    s1 = "CMSEL,S,%s" % master
    c1 = "! 选择主面组件/结点集<%s>." % master
    s2 = "TYPE,etmax+1"
    c2 = "! 激活目标单元类型号<etmax+1>."
    s3 = "ESURF,"
    c3 = "! 创建上覆表面单元/TARGET170."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    s4 = "ALLSEL,ALL"
    c4 = "! Select Everything."
    s5 = "CMSEL,S,%s" % slave
    c5 = "! 选择从面组件/结点集<%s>." % slave
    s6 = "TYPE,etmax+2"
    c6 = "! 激活接触单元类型号<etmax+2>."
    s7 = "ESURF,"
    c7 = "! 创建上覆表面单元/CONTACT174."
    s8 = "ALLSEL,ALL"
    c8 = "! Select Everything."
    cmds = cmds + [[s9, c9], [s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8]]
    return cmds



9.3 创建点-面耦合约束


def create_coupling_constraint(master, slave, dofs="111111", csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建点-面耦合/如加载点与加载面的耦合
    # 参数:master为控制点所在组件名称;slave为从面结点所在组件名称。
    # 参数:dofs为被约束的自由度(指点面间),dof=111111表示6个自由度均被约束。
    # 参数:1表示该自由被约束,0表示该自由度未被约束,如100011表示 UX, UY, 和 ROTZ 三个自由度被约束。
    # 参数:csys为被约束的自由度所采用的坐标系,默认为0即全局直角坐标系。
    # 返回:APDL命令流。
    cmds = []
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CSYS,%s" % csys
    c3 = "! 激活坐标系/坐标系编号<%s>." % csys
    s4 = "CMSEL,S,%s" % master
    c4 = "! 选择控制点所在组件/结点集<%s>." % master
    s5 = "CMSEL,A,%s" % slave
    c5 = "! 补选从面接结点所在组件/结点集<%s>." % slave
    s6 = "NROTAT,ALL"
    c6 = "! 旋转结点坐标系使之与激活坐标系平行."
    s7 = "ALLSEL,ALL"
    c7 = "! Select Everything."
    s8 = "*GET,etmax,ETYP,,NUM,MAX"
    c8 = "! 当前最大单元类型编号<etmax>."
    s9 = "*GET,rlmax,RCON,,NUM,MAX"
    c9 = "! 当前最大实常数编号<rlmax>."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    s1 = "R,rlmax+1"
    c1 = "! 定义实常数/实常数编号<rlmax+1>."
    s2 = "REAL,rlmax+1"
    c2 = "! 激活实常数/实常数编号<rlmax+1>."
    s3 = "ET,etmax+1,TARGE170"
    c3 = "! 定义目标面单元/连续面/单元编号<etmax+1>."
    s4 = "KEYOPT,etmax+1,2,1"
    c4 = "! 设置单元关键项/KEYOPT(2)=1."
    s5 = "KEYOPT,etmax+1,4,%s" % dofs
    c5 = "! 设置单元关键项/KEYOPT(4)=%s." % dofs
    s6 = "ET,etmax+2,CONTA174"
    c6 = "! 定义接触面单元/离散面/单元编号<etmax+2>."
    s7 = "KEYOPT,etmax+2,2,2"
    c7 = "! 设置单元关键项/KEYOPT(2)=2."
    s8 = "KEYOPT,etmax+2,4,1"
    c8 = "! 设置单元关键项/KEYOPT(4)=1."
    s9 = "KEYOPT,etmax+2,12,5"
    c9 = "! 设置单元关键项/KEYOPT(12)=5."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    s1 = "ALLSEL,ALL"
    c1 = "! Select Everything."
    s2 = "CMSEL,S,%s" % master
    c2 = "! 选择控制点所在组件/结点集<%s>." % master
    s3 = "*GET,ndnum,NODE,,NUM,MAX"
    c3 = " 控制点结点编号<ndmax>."
    s4 = "TYPE,etmax+1"
    c4 = "! 激活目标单元类型号<etmax+1>."
    s5 = "TSHAP,PILO"
    c5 = "! 设置目标单元几何形状/导向结点."
    s6 = "E,ndnum"
    c6 = "! 创建单元/在控制点处创建目标单元."
    s7 = "ALLSEL,ALL"
    c7 = "! Select Everything."
    s8 = "CMSEL,S,%s" % slave
    c8 = "! 选择从面结点所在组件/结点集<%s>." % slave
    s9 = "TYPE,etmax+2"
    c9 = "! 激活接触单元类型号<etmax+2>."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    s1 = "ESURF,"
    c1 = "! 创建上覆表面单元/CONTACT174."
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CSYS,0"
    c3 = "! 激活全局直角坐标系."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], ]
    return cmds



9.4 创建点-点约束方程


def create_constraint_equation(node1, node2, dof="UX", csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建约束方程/强制两个结点某一自由度相等/其他情况本函数未考虑
    # 参数:node1、node2: 建立约束方程的两个结点所在的组件名称。
    # 参数:dof: 两节点相等的自由度值的标签,可以为:ROTZ, ROTY, ROTX, UZ, UY, UX。
    # 参数:csys为约束方程建立时所采用的坐标系,即dof生效的坐标系编号,默认值为0即全局笛卡尔坐标系。
    cmds = []
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CSYS,%s" % csys
    c3 = "! 激活坐标系/坐标系编号<%s>." % csys
    s4 = "CMSEL,S,%s" % master
    c4 = "! 选择控制点所在组件/结点集<%s>." % master
    s5 = "CMSEL,A,%s" % slave
    c5 = "! 补选从面接结点所在组件/结点集<%s>." % slave
    s6 = "NROTAT,ALL"
    c6 = "! 旋转结点坐标系使之与激活坐标系平行."
    s7 = "ALLSEL,ALL"
    c7 = "! Select Everything."
    s8 = "CMSEL,S,%s" % node1
    c8 = "! 选择主结点组件/结点集<%s>." % node1
    s9 = "*GET,n1,NODE,,NUM,MAX"
    c9 = "! 获取主结点编号<n1>." % node1
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9]]
    s1 = "CMSEL,S,%s" % node2
    c1 = "! 选择从结点组件/结点集<%s>." % node2
    s2 = "*GET,n2,NODE,,NUM,MAX"
    c2 = "! 获取从结点编号<n2>." % node2
    s3 = "ALLSEL,ALL"
    c3 = "! Select Everything."
    s4 = "CE,NEXT,0,n1,%s,1,n2,%s,-1" % (dof, dof)
    c4 = "! 创建约束方程/点<n1>和点<n2>/相等自由度<%s>/坐标系<%s>." % (dof, csys)
    s5 = "CSYS,0"
    c5 = "! 激活全局直角坐标系."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5]]
    return cmds




十、加载/求解/场输出


10.1 位移边界条件




def define_boundary_condition(compname, dofs=111111, csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:定义边界条件
    # 参数:compname为施加位移边界条件各结点所在的组件/集合名称
    # 参数:dofs为被约束的自由度(指点面间),dofs=111111表示6个自由度均被约束。
    # 参数:dofs的六位数因此表示的六个方向为:ROTZ, ROTY, ROTX, UZ, UY, UX。
    # 参数:1表示该自由被约束,0表示该自由度未被约束,如100011表示 UX, UY, 和 ROTZ 三个自由度被约束。
    # 参数:csys为位移边界条件生效的坐标系,默认为0,即采用整体笛卡尔坐标系。
    # 返回:APDL命令流
    cmds = []
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CSYS,%s" % csys
    c3 = "! 激活坐标系/坐标系编号<%s>." % csys
    s4 = "CMSEL,S,%s" % compname
    c4 = "! 选择组件/边界各结点组件/结点集<%s>." % compname
    s5 = "NROTAT,ALL"
    c5 = "! 旋转结点坐标系使之与激活坐标系平行."
    s6 = "ALLSEL,ALL"
    c6 = "! Select Everything."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6]]
    doflabels = ["UX", "UY", "UZ", "ROTX", "ROTY", "ROTZ"]
    ss = []
    for i in range(6):
        val = dofs[-(i + 1)]
        if val == "1":
            ss.append(doflabels[i])
    for label in ss:
        s7 = "D, ALL, %s, 0" % label
        c7 = "! 施加边界条件/固定边界<%s=0>/坐标系<%s>." % (label, csys)
        cmds.append([s7, c7])
    s8 = "CSYS,0"
    c8 = "! 激活全局直角坐标系."
    cmds = cmds + [[s8, c8], ]
    return cmds



10.2 荷载边界条件


def apply_force_loads(compname, fx=0, fy=0, fz=0, mx=0, my=0, mz=0, csys=0):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:施加集中力/集中弯矩荷载
    # 参数:compname为施加荷载结点所在的组件/集合名称
    # 参数:fx、fy和fz为三个方向上的集中力;
    # 参数:mx、my和mz为三个方向上的弯矩值。
    # 参数:csys为施加的荷载所采用的坐标系,默认为0,即采用整体笛卡尔坐标系。
    # 返回:APDL命令流
    cmds = []
    s1 = "/PREP7"  # 命令
    c1 = "! Enters the model creation preprocessor."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "CSYS,%s" % csys
    c3 = "! 激活坐标系/坐标系编号<%s>." % csys
    s4 = "CMSEL,S,%s" % compname
    c4 = "! 选择组件/边界各结点组件/结点集<%s>." % compname
    s5 = "NROTAT,ALL"
    c5 = "! 旋转结点坐标系使之与激活坐标系平行."
    s6 = "ALLSEL,ALL"
    c6 = "! Select Everything."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6]]
    loads = [fx, fy, fz, mx, my, mz]
    labels = ["FX", "FY", "FZ", "MX", "MY", "MZ"]
    ss = []
    for i in range(6):
        load, label = loads[i], labels[i]
        if load != 0.0:
            ss.append([label, load])
    num = len(ss)
    for i in range(num):
        label, load = ss[i]
        s7 = "F,%s,%s,%s" % (compname, label, load)
        c7 = "! 施加荷载/荷载作用点<%s>/荷载数值<%s=%s>." % (compname, label, load)
        cmds.append([s7, c7])
    s8 = "CSYS,0"
    c8 = "! 激活全局直角坐标系."
    cmds = cmds + [[s8, c8], ]
    return cmds




10.3 分析步与分析步文件


10.3.1 创建模态分析步


def create_frequency_step(freq=50, f1=0, f2=100):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建模态分析步
    # 参数:freq为模态分的阶数/模态提取阶数/The number of modes to extract。
    # 参数:f1、f2为感兴趣频带的起点和终点频率,单位为Hz。
    # 返回:APDL命令流。
    cmds = []
    s1 = "/SOLU"  # 命令
    c1 = "! Enters the solution processor/访问求解器模块."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "ANTYPE,MODAL"
    c3 = "! 设置分析类型/模态分析."
    s4 = "MODOPT,LANB,%s" % freq
    c4 = "! 模态分析方法<Block Lanczos>/模态提取阶数<%s>." % freq
    s5 = "EQSLV,SPAR"
    c5 = "! 求解方法/SPAR."
    s6 = "MXPAND,0,,,0"
    c6 = "! 默认设置."
    s7 = "LUMPM,0"
    c7 = "! 默认设置."
    s8 = "PSTRES,0"
    c8 = "! 默认设置."
    s9 = "MODOPT,LANB,%s,%s,%s,,OFF" % (freq, f1, f2)
    c9 = "! 模态阶数<%s>/起点频率<%s>/终点频率<%s>." % (freq, f1, f2)
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9], ]
    return cmds



10.3.2 创建静力通用分析步


def create_static_general_step(maxsub, minsub):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建静力通用分析步
    # 参数:maxsub为荷载大步数/Number of substeps to be used for this load step。
    # 参数:minsub为荷载小步数/Number of substeps to be used for this load step。
    # 返回:APDL命令流。
    cmds = []
    s1 = "/SOLU"  # 命令
    c1 = "! Enters the solution processor/访问求解器模块."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "ANTYPE,STATIC"
    c3 = "! 设置分析类型/静力分析."
    s4 = "NLGEOM,OFF"
    c4 = "! 关闭几何非线性."
    s5 = "EQSLV,PCG,1E-4"
    c5 = "! 预条件共轭梯度法/公差<1E-4>."
    s6 = "NSUBST,%s,%s,%s" % (maxsub, maxsub, minsub)
    c6 = "! 初始荷载子步数<%s>/最大子步数<%s>/最小子步数<%s>." % (maxsub, maxsub, minsub)
    s7 = "AUTOTS,ON"
    c7 = "! 自动荷载步(浮动荷载步)/默认设置."
    s8 = "KBC,0"
    c8 = "! 设置加载方式/渐变方式荷载步/比例加载."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], ]
    return cmds



10.3.3 创建荷载步文件


def create_load_step_file(lsnum):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建荷载步文件
    # 参数:lsnum为荷载步文件识别号,lsnum尽量小于99。
    # 返回:APDL命令流
    cmds = []
    s1 = "/SOLU"  # 命令
    c1 = "! Enters the solution processor/访问求解器模块."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "LSWRITE,%s" % lsnum
    c3 = "! 创建荷载步文件/载荷步文件编号<%s>." % lsnum
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], ]
    return cmds



10.3.4 创建静力重启动分析步


def create_static_restart_analysis(oldjobname, newjobname, maxsub, minsub, oldlsnum=1):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建静力重启动分析步
    # 参数:oldjobname为原作业名称;newjobname为重启动后的新作业名称。
    # 参数:oldjobname为原作业名称;newjobname为重启动后的新作业名称。
    # 参数:maxsub为荷载大步数/Number of substeps to be used for this load step。
    # 参数:minsub为荷载小步数/Number of substeps to be used for this load step。
    # 参数:oldlsnum: 原作业所对应的荷载步识别号,应小于99。
    # 返回:APDL命令流。
    tmps1 = str(oldlsnum)
    tmps2 = tmps1.rjust(2, "0")
    tmps3 = "s" + tmps2
    oldlsname = "%s.%s" % (oldjobname, tmps3)
    s1 = "FINISH"  # 命令
    c1 = "! 退出当前处理器."  # 备注
    s2 = "/FILNAME,%s,0"
    c2 = "! 设置作业名称<%s>/结果文件名称<%s.rst>." % (newjobname, newjobname)
    s3 = "/COPY, '%s','rdb','','%s','rdb',''" % (oldjobname, newjobname)
    c3 = "! 复制并重命名文件."
    s4 = "/COPY, '%s','rdb','','%s','rdb',''" % (oldjobname, newjobname)
    c4 = "! 复制并重命名rdb文件."
    tmps4 = str(oldlsnum)
    tmps5 = tmps4.rjust(3, "0")
    rnnn = "r" + tmps5
    s5 = "/COPY, '%s','%s','','%s','%s',''" % (oldjobname, rnnn, newjobname, rnnn)
    c5 = "! 复制并重命名文件."
    s6 = "/COPY, '%s','ldhi','','%s','ldhi',''" % (oldjobname, newjobname)
    c6 = "! 复制并重命名文件."
    s7 = "/SOLU"  # 命令
    c7 = "! Enters the solution processor/访问求解器模块."  # 备注
    s8 = "ALLSEL,ALL"
    c8 = "! Select Everything."
    s9 = "/DELETE,'parameter','txt',''"
    c9 = "! 删除文件/Do循环时的必要操作."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], [s9, c9], ]
    s1 = "PARSAVE,SCALAR,parameter,txt"  # 命令
    c1 = "! 保存参数/Do循环时的必要操作."  # 备注
    s2 = "ANTYPE,STATIC,RESTART"
    c2 = "! 设置分析类型/静力重启动分析."
    s3 = "PARRES,CHANGE,'parameter','txt',''"
    c3 = "! 修改参数/Do循环时的必要操作."
    s4 = "NLGEOM,OFF"
    c4 = "! 关闭几何非线性."
    s5 = "EQSLV,PCG,1E-4"
    c5 = "! 预条件共轭梯度法/公差<1E-4>."
    s6 = "NSUBST,%s,%s,%s" % (maxsub, maxsub, minsub)
    c6 = "! 初始荷载子步数<%s>/最大子步数<%s>/最小子步数<%s>." % (maxsub, maxsub, minsub)
    s7 = "AUTOTS,ON"
    c7 = "! 自动荷载步(浮动荷载步)/默认设置."
    s8 = "KBC,0"
    c8 = "! 设置加载方式/渐变方式荷载步/比例加载."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3], [s4, c4], [s5, c5], [s6, c6], [s7, c7], [s8, c8], ]
    return cmds



10.4 场输出


def create_field_output(compnames=None):
    # 作者:DalNur;邮箱:liyang@alu.hit.edu.cn
    # 功能:创建场输出
    # 参数:compnames为输出数据的单元组件名称列表,若为None,则输出整个模型的数据。
    # 返回:APDL命令流。
    cmds = []
    s1 = "/SOLU"  # 命令
    c1 = "! Enters the solution processor/访问求解器模块."  # 备注
    s2 = "ALLSEL,ALL"
    c2 = "! Select Everything."
    s3 = "OUTRES,ERASE"
    c3 = "! 恢复场输出的默认设置."
    cmds = cmds + [[s1, c1], [s2, c2], [s3, c3]]
    if compnames is None:
        # 采用默认场输出
        s4 = "OUTRES,ALL,ALL"
        c4 = "! 设置输出频次/Item=All/Freq=All(输出每个子步)."
        s5 = "! OUTRES,ALL,LAST "
        c5 = "! 设置输出频次/Item=All/Freq=Last(仅输出最后子步)."
        cmds = cmds + [[s4, c4], [s5, c5]]
    else:
        s4 = "OUTRES,ALL,None"
        c4 = "! 抑制全部场输出."
        cmds = cmds + [[s4, c4]]
        for cname in compnames:
            s5 = "OUTRES,ALL,LAST,%s" % cname
            c5 = "! Item=ALL/Freq=Last/输出的组件名称<%s>." % cname
            cmds.append([s5, c5])
    return cmds



十一、后处理


  详见博客专栏:ANSYS 参数化建模 实用教程




十二、致谢


  特别感谢朋友们曾经对我各种弱智问题的耐心解答,提前祝离职的、将要离职的,仍然在职的你们,辛丑牛年,中秋快乐!





十三、尾声


  行文至此,自动化创建 ANSYS APDL 命令流的各主要 Python 函数已创建完毕。

  根据本文列出的各 Python 函数,可排列组合出在 ANSYS 中复建模型的 APDL 命令流。

  本文是博主阿阳哥 Python 自动化建模技术的重要组成部分,因此偏向于自下而上创建有限元模型。

  本文的顺利完成,标志着博主在这方面近四年的努力取得阶段性胜利,相关工作亦接近尾声。

  如有疑问、合作需求及推荐工作,请联系邮件联系本人,Email: liyang@alu.hit.edu.cn

  本文仅用于个人学习,除此之外,无其他任何用途。

  因个人水平有限,文中难免有所疏漏,还请各位大神不吝批评指正。

  胸藏文墨怀若谷,腹有诗书气自华,希望各位都能在知识的 pāo 子里快乐徜徉。

  本文首次发表于 2021-09-15 16:46:21,Beijing 。

  如无特殊原因,不再更新!本文逻辑清楚,内容详实。

  欢迎大家点赞、评论及转载,转载请注明出处!

  为我打call,不如为我打款!

  最后,祝各位攻城狮们,珍爱生命,保护发际线!



在这里插入图片描述






十四、参考文献


[1]. ANSYS Mechanical APDL Command Reference. Release 2020.R2.

[2]. ANSYS Mechanical APDL Element Reference. Release 2020.R2.

[3]. ANSYS 参数化建模 实用教程. 阿阳.





  • 49
    点赞
  • 227
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 32
    评论
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hulunbuir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值