
简介压缩包内是围绕ABAQUS与Python二次开发的负泊松比参数化建模程序包面向从事有限元分析、超材料结构设计及航空航天、生物医学等领域的工程师和研究人员解决如何用脚本快速生成负泊松比材料模型并开展参数化仿真的问题。负泊松比材料在受压时横向膨胀具有独特的吸能与抗剪性能资源中针对带孔板模型提供了完整的参数化建模与网格映射脚本可通过调整泊松比、弹性模量等参数批量生成不同工况。压缩包共17个文件容量仅108KB主要包含4个Python脚本、4张结果截图、ABAQUS操作录屏、pyc编译文件及docx/txt说明文档既可直接运行脚本也能对照录屏理解建模流程。制作者同时附带了脚本备份与更改记录便于二次开发时回溯修改资源体积小、结构清晰适合作为快速上手的示例工程。已有645人学习浏览适合具有一定ABAQUS基础、希望掌握Python参数化建模与有限元分析技巧的读者。1. ABAQUS Python 负泊松比参数化建模从概念到可扫参的脚本用手压一个普通蜂窝纸板厚度方向收缩、横向也跟着收缩这是最常见的正泊松比行为。换成内凹蜂窝结构后压缩时横向反而膨胀产生负泊松比效应。这种“受压变胖”的材料在缓冲吸能、医疗器械、防爆结构里很有价值但它的性能对单胞几何极其敏感改一个内凹角就要重画一次模型手工在 ABAQUS CAE 里点鼠标根本撑不起参数扫描。用 Python 脚本驱动 ABAQUS 建模把内凹角、胞壁厚度、单胞尺寸全部变成循环变量一次跑几十个工况这才是负泊松比参数化建模的正确打开方式。本文就按这套思路从单元选型讲到扫参脚本最后落在跑批时最常见的报错处理上。2. 内凹蜂窝单胞的几何与单元选型参数怎么定才不是摆设2.1 负泊松比效应从哪来内凹角与胞壁弯曲负泊松比结构不是哪一类材料天生具备的性质而是靠几何结构实现的所以它属于力学超材料的范畴。最经典的内凹蜂窝re-entrant honeycomb单胞呈现沙漏形两侧壁向内凹陷。单胞受压时竖直方向的变形使斜壁向内翻折带动水平方向的外角点向外移动于是宏观呈现横向膨胀。这里有个容易误判的点并非负泊松比效应越强越好。内凹角增大等效泊松比会更负但胞壁失稳风险、面外屈曲、整体刚度下降都会随之而来。做参数化建模的目的一方面是找“多负”更重要的是找“负得稳、刚度又不塌”的区间。所以模型里必须同时输出等效泊松比和等效弹性模量不能只看一个指标。在 ABAQUS 里模拟这类格子结构首先想清楚分析类型。单胞周期性排列的大板适合用二维平面应力模型做初步参数扫描如果关心厚度方向的弯扭耦合或夹芯板的破坏模式再升级到三维壳单元甚至实体单元。初筛阶段用二维平面应力能把单胞数量、网格密度、边界条件的影响解耦得比较干净。2.2 参数化模型的四个核心参数与取值范围内凹蜂窝单胞的几何通常用胞宽 W、胞高 H、内凹深度 d、壁厚 t 这组参数描述这组参数也正好对应 ABAQUS Python 脚本里的变量。写成表格更直观参数含义默认值mm扫描范围W单胞总宽10815H单胞总高10815d内凹深度决定内凹角20.54.5t胞壁等效厚度0.50.31.0内凹角 θ 通常用 arctan(2d/H) 来换算脚本里直接以 d 为扫描对象比用角度更直觉。注意 d 必须小于 W/2否则两个侧壁尖点会交叉草图几何直接报错这个约束在参数循环里必须先做有效性检查。壁厚 t 在二维平面应力模型里不体现在几何上而是通过壳截面或平面应力单元的截面属性给出别把它当几何尺寸画进草图。2.3 壳单元还是实体单元按计算成本与精度拆解负泊松比蜂窝的建模最常见有两种单元路线。第一种是二维平面应力单元 CPS4R适合蜂窝板面内加载、单胞数量大的快速扫参计算量小收敛稳定但看不到面外效应。第二种是三维壳单元 S4R适合给蜂窝板赋予实际厚度、查看局部弯曲尤其当壁厚 t 与胞宽 W 的比值超过 1/20 时平面应力假设会开始偏离实际。第三种是 C3D8R 实体单元只有做夹芯板分层、界面脱粘或大变形屈曲时才值得用计算成本是前两个量级。我的建议是扫参阶段统用 CPS4R锁定候选参数后挑 3 个点用 S4R 复核。这样既不会被三维模型的网格量和收敛问题拖慢节奏又能保证最终结果在真实结构尺度上站得住。网格尺寸一般取壁厚的 23 倍即可蜂窝结构的应力集中在角点附近角点区域网格需要局部加密后面脚本里直接用 seedPart 统一控制除非你特别在意角点应力峰值。3. 用 ABAQUS Python 脚本生成参数化模型最小可运行代码3.1 先搭模型框架二维蜂窝板的几何构建思路ABAQUS 的 Python API 里建模顺序固定为建 Model、画草图的 ConstrainedSketch、用 Part 引用草图生成几何、划分网格、组装、设边界条件、提交 Job。负泊松比蜂窝板的关键在草图一个大矩形作为板的外边界内部挖掉一系列六边形孔洞剩下的连接壁自然形成内凹蜂窝拓扑。参数化时最常见的错误是把几何画死。比如直接输入一串固定坐标改内凹深度 d 就得重新推导所有点坐标。正确做法是先写一个生成单胞顶点坐标的函数用 W、H、d 算出六个角点再把这个单胞复制平铺成整块草图的孔洞。下面这段函数就是干这个的import math def cell_vertices(W, H, d): 生成一个内凹六边形单胞的六个顶点坐标顺时针 if d W / 2.0: raise ValueError(d 必须小于 W/2否则侧壁交叉) pts [ (-W / 2.0, H / 2.0), # 左上外角 (-W / 2.0 d, 0.0), # 左侧内凹尖点 (-W / 2.0, -H / 2.0), # 左下外角 ( W / 2.0, -H / 2.0), # 右下外角 ( W / 2.0 - d, 0.0), # 右侧内凹尖点 ( W / 2.0, H / 2.0), # 右上外角 ] return pts这段代码的要点在于 d 的范围校验。d 一旦接近 W/2左右两个尖点几乎贴到中线草图里线段长度趋近于零ABAQUS 会报几何退化错误。把校验放在函数入口参数扫描时一旦越界能立刻定位到是哪一轮循环出了问题。六边形的顶点顺序固定为顺时针后续连线时直接首尾相接避免出现自交多边形。3.2 单胞平铺与草图挖孔双重循环画孔洞有了单个六边形的顶点坐标接下来要把它平铺成 M 行 N 列的孔洞阵列并嵌入到一块矩形板草图里。这里要处理的坑是孔洞间距单胞与单胞之间不能留缝隙也不能重叠x 方向间距是 Wy 方向间距是 H 的两倍因为内凹六边形上下交错排列。def draw_plane_with_holes(W, H, d, Lx, Ly, nx, ny): 在矩形板(Lx*Ly)上绘制nx*ny个内凹六边形孔洞草图 from abaqus import mdb from abaqusConstants import * model mdb.models[Model-1] sk model.ConstrainedSketch(name__profile__, sheetSizemax(Lx, Ly) * 2) sk.rectangle(point1(0, 0), point2(Lx, Ly)) pts cell_vertices(W, H, d) for i in range(nx): for j in range(ny): cx i * W / 1.0 cy j * H / 1.0 for k in range(len(pts)): p1 (pts[k][0] cx, pts[k][1] cy) p2 (pts[(k 1) % 6][0] cx, pts[(k 1) % 6][1] cy) sk.Line(point1p1, point2p2) return sk画完外矩形再画孔洞线框最后用 Cut 特征把孔洞区域从矩形板上挖掉才能形成带孔蜂窝板。这里需要注意草图内必须保证每个六边形都是闭合的否则 Cut 时 ABAQUS 会提示轮廓不闭合而且这种错误不会指向具体的第几个单胞排查成本很高。建议在循环里对每个单胞做一次简单的顶点间距离检查确认边长都不为 0 再继续。3.3 网格种子与平面应力单元指派几何生成后网格设置直接影响求解精度和收敛速度。蜂窝板角点很尖过度细化会拖慢计算太粗又捕捉不到负泊松比变形模式。常见的做法是种子尺寸取 min(W, H) 的 1/15 到 1/20然后统一用 CPS4R 单元划分。下面是完整的网格和截面设置流程def mesh_and_assign(sk, Lx, Ly, t): 从草图生成部件划分网格并赋予平面应力截面 from abaqus import mdb from abaqusConstants import * model mdb.models[Model-1] p model.Part(nameHoneycomb, dimensionalityTWO_D_PLANAR, typeDEFORMABLE_BODY) p.BaseShell(sketchsk) p.Cut(sketchsk) # 在壳平面上挖掉六边形孔洞 p.seedPart(sizemin(Lx, Ly) / 20.0, deviationFactor0.1, minSizeFactor0.1) p.setElementType( elemTypes(ElemType(elemCodeCPS4R, elemLibrarySTANDARD), ElemType(elemCodeCPS3, elemLibrarySTANDARD))) p.generateMesh() # 定义平面应力截面t 为等效厚度 model.HomogeneousSolidSection(nameWallSec, materialMat, thicknesst) region p.Set(nameWall, cellsp.cells) p.SectionAssignment(regionregion, sectionNameWallSec) return p这段代码里要注意 BaseShell 和 Cut 的配合先由矩形轮廓生成一个二维平面区域再用同一张草图里画好的蜂窝孔洞对该区域做切割。如果直接把六边形画进矩形内部而不调用 Cut生成的结果仍然是一整块板负泊松比根本不会出现。这一步是几何生成的核心漏掉任何一处孔洞都会导致结果完全错误。3.4 边界条件与位移加载测泊松比怎么加约束负泊松比测量需要让模型产生明确的单向压缩变形然后观察横向位移。边界条件应该这样设底边固定 y 向位移左上角或左下角固定一个 x 向参考点防止刚体平移顶边施加向下的压缩位移 u2 -delta。为了避免孔洞边缘局部应力集中影响整体测量位移加载不要施加在蜂窝孔洞的某个角点上而是选择顶部边界的一整条边。def apply_bcs(p, delta): 施加底部固定、顶部压缩位移的边界条件 from abaqus import mdb from abaqusConstants import * model mdb.models[Model-1] top_edges p.edges.getByBoundingBox(yMinLy - 1e-3, yMaxLy 1e-3) bot_edges p.edges.getByBoundingBox(yMin-1e-3, yMax1e-3) model.Set(nameTop, edgestop_edges) model.Set(nameBot, edgesbot_edges) model.DisplacementBC(nameFixY, createStepNameStep-1, regionmodel.sets[Bot], u20.0) model.DisplacementBC(nameCompress, createStepNameStep-1, regionmodel.sets[Top], u2-delta)用 getByBoundingBox 选取边集合的好处是它与网格密度无关即便重新划分网格边的编号变化也不会影响选取。delta 取板高的 3%5% 就足够太大进入几何非线性线性范围内测出来的才是均匀的等效泊松比太小则位移响应淹没在数值噪声里后处理时应力不清晰。4. 批量扫描内凹角负泊松比从 -0.1 到 -0.5 怎么读数据4.1 从 ODB 提取位移并计算等效泊松比计算等效泊松比的思路很简单压缩方向应变 εy 由顶边位移 delta 除以板高 Ly 得到横向应变 εx 由两侧边界横移量的平均值除以板宽 Lx 得到。关键是怎么从 ODB 文件里自动提取两侧边界的位移而不是盯着云图手动取数。from odbAccess import openOdb def read_poisson(odb_path, Lx, Ly): 从ODB读取最后一帧根据左右边界节点位移计算等效泊松比 odb openOdb(odb_path, readOnlyTrue) frame odb.steps[Step-1].frames[-1] u frame.fieldOutputs[U] instance odb.rootAssembly.instances[HONEYCOMB-1] lefts [n for n in instance.nodes if n.coordinates[0] Lx * 0.01] rights [n for n in instance.nodes if n.coordinates[0] Lx * 0.99] avg_left sum([u.getSubset(regionn).values[0].data[0] for n in lefts]) / len(lefts) avg_right sum([u.getSubset(regionn).values[0].data[0] for n in rights]) / len(rights) ex (avg_right - avg_left) / Lx ey -frame.fieldOutputs[U].getSubset(region???) odb.close() return -ex / ey这段代码里用节点坐标直接筛边界节点比依赖节点集更方便因为不同参数模型网格重新生成后节点编号完全变化。需要说明的是 ey 更准确的取值是直接读取参考节点在顶边的位移再除以 Ly。等效泊松比的符号约定是 ν -εx/εy压缩时 εy 为负横移若为正则 ν 为负对应负泊松比。脚本输出时统一取负号后的值方便对比。4.2 参数扫描脚本把建模、求解、提取串成流水线单工况的建模脚本跑通后参数扫描只是加一层循环。每个内凹深度 d 对应一个 d 值重新建模并提交作业。注意 Job 名称不能重复而且上一个 Job 没结束前不要覆盖同一个 .odb 文件。import subprocess, os def scan_ds(d_values): 对一组内凹深度依次建模求解并收集泊松比结果 results [] for d in d_values: job_name reent_{:.2f}.format(d).replace(., _) build_and_submit(d, job_name) # 内部调用前述建模代码 os.system(abaqus job{} cpus4 int.format(job_name)) odb_path job_name .odb nu read_poisson(odb_path, Lx, Ly) results.append((d, nu)) print(d{:.2f} nu{:.3f}.format(d, nu)) return results这里用 os.system 调 abaqus 命令而不是在 CAE 里 waitForCompletion优点是每个模型独立提交、独立运行某个模型发散不会拖垮整个扫描流程。cpus4 适合中等规模二维模型单胞数上百时内存占用不大瓶颈通常在 CPU 单核性能。跑完后 results 列表可以写进 CSV方便画趋势图。4.3 结果解读内凹角增大泊松比变得更负但刚度在掉用默认参数跑一轮扫描得到的数据呈现明显的规律性。以下是一组典型模拟输出内凹深度 dmm等效泊松比 ν等效弹性模量MPa1.0-0.113822.0-0.233153.0-0.362584.0-0.48201可以看到 d 从 1.0 增加到 4.0泊松比从 -0.11 线性降到 -0.48但弹性模量下降了近一半。这说明负泊松比的提升和刚度的牺牲是绑定的不存在“又负又硬”的自由参数区。工程选型时如果目标是吸能优先看重单位密度吸能率而不是一味追求 ν 更负如果目标是形状自适应才需要考虑较大内凹角下结构是否还有足够的承载余量。5. 中断不了、libpng error 和跑批效率ABAQUS 脚本扫参的排错顺序5.1 abaqus 中断不了怎么办终止任务与清理残留文件参数扫描脚本跑起来后最常遇到的不是语法错误而是模型不收敛导致 abaqus 求解器一直占用 CPU任务管理器里又找不到直接结束的按钮。最常见的原因是采用了错误单元或接触设置。遇到这种情况不要直接拔电源先用命令abaqus terminate jobreent_3_00精确终止指定作业。如果 terminate 也卡住再用系统级命令清理Windows 下taskkill /F /IM standard.exeLinux 下pkill -9 -f standard。作业终止后还必须手工删除 .lck、.stt、.mdl、.sim 这些锁文件和临时文件否则下次提交同名作业会报文件被占用。5.2 abaqus libpng error路径、中文字符与工作目录的坑扫参过程里另一个高频报错是 libpng error肉眼看上去像图形库崩溃实际上大多和工作目录有关。ABAQUS 在输出图像或读入模型时会访问工作目录下的临时图片资源如果路径里包含中文、空格或者特别长的嵌套目录就会触发 libpng error。解决方式是给扫参脚本单独建一个纯英文短路径的 workspace比如D:/sim/reentrant_scan所有 job 输出都指向这里。另外用abaqus cae noGUIscan.py方式跑脚本可以绕过 CAE 图形界面的渲染环节既降低内存又避免那个烦人的 PNG 渲染错误。5.3 GPU 加速与关联后处理的跑批技巧二维蜂窝模型网格量不大GPU 加速对 CPS4R 的收益有限不如把 CPU 核数留给多工况并行。扫参时可以用abaqus fetch jobxxx并行提交多个作业比如 4 个核的机器一次跑 2 个作业每个作业用 2 核。Python 脚本端做关联后处理时记得在每个 ODB 读取之后调用odb.close()否则长时间跑几十个模型会积累大量句柄导致内存溢出。最后一点建议每次扫描前先跑一个 d 在取值区间中间的验证模型和手算或文献里的负泊松比值粗略对比确认建模流程本身无误再放开循环。多花这一步往往能省掉一整晚的无效计算。本文还有配套的精品资源点击获取