☰
提示工程实战:用GPT让材料力学本构模型变成可运行Python代码
2026/10/9 7:04:56 网站建设 项目流程

读博那阵子,最让我头疼的不是推导那些复杂的本构方程,而是好不容易把物理模型推明白了,结果卡在“把方程写成能跑的 Python 代码”这一步上。计算材料科学和力学仿真这类任务,真正磨人的往往不是理论本身,而是围绕理论模型的一圈工程化脏活——批量处理数据、迭代求解方程组、结果可视化、参数标定。直到我开始用 GPT 配合提示工程来干活,这一块的效率才真正提了上来。这篇系列的第一篇,我就从提示工程入手,挑几个材料力学里真实会碰到的编程场景,完整走一遍“提出问题—设计提示词—生成代码—迭代修正”的流程,希望能帮你把这个协作套路用起来。

1. 提示工程在计算材料科学编程里的定位

1.1 为什么写代码这一步成了瓶颈

做计算材料科学和力学编程的人,大概都有同感:我们不是软件工程师,但每天要写大量科学计算代码。读文献时看懂一个晶体塑性本构模型不难,难的是把那些带张量下标、积分格式、增量迭代算法的公式变成能跑出结果的 Python 程序。我读硕的时候,光是把一个简单的线性强化弹塑性模型写成可用的代码,就折腾了快一星期——公式没理解错,但 numpy 广播维度对不上、循环里状态变量更新顺序搞反、单位制没统一,各种问题叠在一起,一天天净跟报错信息较劲。

后来我开始用 GPT 辅助编程,体验完全不一样。它的强项恰好覆盖了这块短板:熟悉 numpy、scipy、matplotlib 等科学计算库的接口,知道常见数值算法的标准写法,还能在你给出物理框架后快速生成一套可运行的代码骨架。但这里有个关键前提——GPT 不懂材料科学,也不懂力学。它生成的代码看起来头头是道,实际上经常把屈服准则写错、把应力更新算法搞混,甚至编造出根本不存在的函数接口。怎么让它“在物理上不犯大错”,这就是提示工程要解决的问题。

1.2 提示工程不是“把需求说清楚”那么简单的

很多人以为提示工程就是“把话说明白”,试过之后发现不是这么回事。我一开始跟 GPT 说“帮我写一个弹塑性本构模型的 Python 代码”,结果它给了我一个学术综述级别的冗长框架,里面全是函数占位符和 TODO 注释,根本不能直接跑。后来我调整了策略,把提示词拆成几个部分:角色设定、任务描述、输入输出格式、约束条件、验证标准,效果立刻就不一样了。

在我实际使用中,一套好用的提示词可以概括为五个要素:明确的角色(你是熟悉材料本构数值实现的 Python 工程师)、具体的物理模型描述(模型类型、控制方程、材料参数、单位制)、输入输出约定(函数接收什么参数、返回什么、数组维度是什么)、实现约束(用 numpy 向量化、不要用 sympy 推导、数值稳定性要求)、验证要求(给出一个测试用例,让代码能自检)。这五个要素缺一个,结果质量都会明显下滑。我把这套东西叫“结构化提示词”,后面每个实例都是按这个框架来的。

1.3 提示工程在这个领域里的特殊难点

当然,计算材料科学编程的提示工程,还有几道独特的坎。首先是物理正确性:GPT 生成的代码语法没问题,但本构模型里某个公式的张量缩并方式可能是错的,强度准则可能把米塞斯和 Tresca 搞混。这意味着你提问的时候,要把公式写得尽量具体,不要想当然认为“它肯定知道”。

其次是状态变量的处理。材料本构的数值实现最怕状态变量更新顺序出错,这类错误在纯函数式代码里根本看不出来,需要把内外变量、历史变量的关系在提示词里讲透彻。

第三个是调试信息的组织。科学计算的报错千奇百怪,维度不匹配、数值发散、计算结果为零等等,每种情况提问的方式都不一样。把我的经验总结一下就是:数值发散时,先让 GPT 帮你检查时间积分格式;维度报错时,把每个数组的 shape 列在提示词里。这些细节在后面章节里我会用实例说明。

2. 核心细节解析与实操要点

2.1 五类高频场景的提示词模板

跟 GPT 配合算材料性能这一年多,我发现日常需求基本跳不出下面五类场景。每类我都整理了一套自己的提示词骨架,用起来直接填空就行。

第一类是公式转代码。这是最基础的,把文献里的本构方程、能量表达式转成 Python。我的模板是:“请把下面这个本构关系写成 numpy 向量化代码,输入为应变张量 eps(形状 n×3×3),材料参数为杨氏模量 E=xxx、泊松比 ν=xxx,输出为应力张量 sigma(同样形状)。注意张量缩并不要用嵌套循环,尽量用 einsum。公式如下:[贴公式]”。

第二类是算法框架生成。比如让你写一个晶体塑性模型的显式时间积分主循环。这种需求我一般会给 GPT 一份伪代码,让它“翻译”成可运行的 Python 结构。提示模板是:“我有如下伪代码描述的算法流程,请把它实现为 Python 类,其中每个时间步调用 update_stress 方法,基于当前变形梯度 F 更新应力 sigma 和状态变量 state。请保留伪代码中的注释,并在关键数值步骤加注释说明物理含义。伪代码:[贴伪代码]”。

第三类是数据可视化。这类需求最容易被轻视,但实际很费时间。我的模板是:“我需要把一组应力-应变曲线画在一张图里,数据分两个文件,第一个文件第一列是应变,第二列是应力(单位 MPa);第二个文件是实验数据,格式一样。请用 matplotlib 绘制双纵轴图,左边显示模型曲线、右边显示实验数据,要求坐标轴字号 14,图例区分模型和实验,并正确标注单位”。

第四类是性能优化。当模型在大批量数据上跑不动时,我会把代码贴给 GPT,问它“这个循环怎么改成向量化写法,或者用 numba 加速”?同时要求它“不要改变计算逻辑,只做性能优化,并解释为什么改完更快”。

第五类是调试排错。这是我用得最多的场景。把报错信息、代码片段、输入数据样例、期望输出四样东西一起扔给 GPT,它的命中率比我逐一排查高得多。经验是不要把代码一整套全贴进去,先定位出错的函数,再把相关上下文给它。

2.2 计算材料力学场景下的提示词设计要点

理论好背,坑难避。把这些模板用到计算材料力学里,还有几个特殊要点必须强调。

一是单位制必须写清楚。我因为没写“应力单位是 MPa 还是 Pa”吃过亏。GPT 默认会把材料参数原样代入公式,如果强度给的是 250 MPa,弹性模量给的是 200 GPa,它可能直接拿来乘,然后画出来的应力是 10 的 8 次方量级,你还要花时间换算回去。现在我的每一条提示词里都会标注“所有参数使用国际单位制(Pa)”,或者说“应力单位为 MPa,画图坐标轴标注 MPa”。

二是张量运算的维度约定。材料力学里到处都是四阶张量、张量缩并,写明维度能避免大量无效沟通。我在提示词里一定会写:“C 是四阶弹性张量,形状 3×3×3×3,sigma 与 eps 都是二阶张量,形状 n×3×3,sigma[i,j] = C[i,j,k,l] eps[k,l](爱因斯坦求和约定)”。

三是强调数值稳定性。计算塑性变形时,如果遇到屈服面上的奇异点,没有任何处理的话代码很容易崩溃。在提示里主动要求“加入材料的塑性一致性处理,在迭代逼近屈服条件时设置公差 tol=1e-8”,明显比事后让 GPT 改要省事。

四是明确输出格式。我一般要求“返回可独立运行的完整代码,包含 import、函数定义和演示用法”,同时“如果代码里需要常量,请放在函数参数中,不要硬编码”。这么做的好处是拿到就能跑,不用手工补依赖。

2.3 用提示词约束 GPT 的“物理想象力”

跟 GPT 打交道的次数多了,我慢慢发现它有一个让人哭笑不得的习惯:遇到不清楚的物理细节,它会自己编一套合理的解释补上去,而不是承认不知道。比如我问它“双相钢的塑性变形怎么模拟”,它会非常有自信地给你一个包含“马氏体相变模型”的复杂代码,完全不管你是不是只需要一个简单的混合法则。

要对付这种“一本正经胡说八道”,最有用的办法是在提示词里把物理假设讲死。我在写提示词时加了一句固定话术:“本任务使用以下材料模型和假设,请严格按照此设定编程,不要引入其他物理机制。若你认为设定在物理上不自洽,请先向我指出,我再确认。” 加了这句话以后,GPT 开始“安安分分”地写代码,不再自作主张加模型。这招在计算力学这种物理约束强的领域特别好用。

3. 实操过程与核心环节实现

3.1 实例一:弹塑性材料单轴拉伸的应力应变响应

纸上谈兵没有用,直接看一个完整的实操过程。最近我接到一个任务,需要给某铝合金结构做一个单轴拉伸的有限元预处理,算它的应力应变曲线。材料是理想弹塑性加线性强化,参数已知,我需要一段 Python 代码来生成模型曲线,并且要和实验数据对比。

我先把需求拆成提示词,按我上一节总结的五要素来组织。完整提示词大致是这样:

你是材料力学数值计算领域的 Python 工程师。请帮我写一个单轴拉伸弹塑性本构模型的求解代码。 模型描述:材料为线性强化弹塑性。屈服准则:单轴应力达到屈服强度 σ_y 后进入塑性,塑性阶段应力按线性强化模量 H 增加,即 σ = σ_y + H * ε_p。弹性阶段 σ = E * ε_e。加载为单调拉伸,应变从 0 到 0.02 线性增加,按应变增量加载。 输入参数(使用国际单位制 Pa): - 弹性模量 E = 200e9 - 屈服强度 sigma_y = 250e6 - 强化模量 H = 1e9 - 最大应变 eps_max = 0.02 - 增量为 100 个等间距步 输出要求: 1. 返回一个函数 calc_stress(eps_array, E, sigma_y, H),输入应变数组,输出应力数组。 2. 函数内部用增量法更新应力与塑性应变,保持状态变量的一致。 3. 在主程序中调用函数,并用 matplotlib 绘制应力-应变曲线,横纵轴标注单位。 4. 不要使用符号推导,直接数值计算。

这个提示词把模型假设、参数、输出都钉死了,GPT 返回了一段相当干净的代码。我简单检查了核心循环的逻辑:弹性段、屈服判断、塑性更新三步清晰,塑性应变的累积也正确。但有个小问题:屈服应变的计算它写成了eps_y = sigma_y / E,直接拿总应变减去弹性应变得到塑性应变,这在单调加载下是对的,不过放到循环里它用了一个eps_eff = eps - sigma_y / E的全局减法,在加载历史复杂时就会出问题。我追问了一句“如果加载历史包含卸载再加载,怎么改?”,它给出了带历史状态变量的版本。这就是迭代的价值——第一版够用,追问第二版才严谨。

我按这个流程跑完,得到的曲线跟实验数据吻合得不错。整个过程包括写提示词、跑代码、修正加载历史逻辑,一共花了一个半小时。要是以前手动从零开始写,光是理顺增量更新的逻辑就得大半天。

3.2 实例二:晶体结构可视化中 ase 与 matplotlib 的配合

第二个实例来自材料科学里很常见的需求:把晶体结构画出来,放到论文里当示意图。前阵子我需要画一个面心立方(FCC)晶胞,并且标出密排面。这个需求听起来简单,但直接手写三维坐标、处理周期性边界条件,烦得很。

我用的提示词是这么写的:

我需要对一个 FCC 铝晶胞做三维可视化。晶格常数 a=4.05 埃。请用 ase 库构建晶体结构,再用 matplotlib 的 Axes3D 绘制原子位置,把原子表示为半径 0.6 埃的球体,晶胞边界用线框画出。另外,请画出(111)密排面,用半透明的红色平面表示,并标出平面法向方向。请输出完整可运行的 Python 代码。

这个提示词在数据集和输出格式上都做了明确要求,GPT 给出了一个合理的实现。运行之后发现两个问题:一是 ase 导出原子坐标时它没有明确去掉边界处的重复原子,导致晶胞顶点原子被重复计数,视觉上亮度不平衡;二是(111)平面的法向向量绘制得过长,超出了晶胞范围,看着很突兀。我继续用对话修正:“请只显示一个晶胞内的独立原子,用周期表符号区分不同元素;法向向量缩短到 1 埃,并加箭头”。第二轮返回的结果就正常了。

这个例子想说明的是:在可视化任务里,GPT 的“第一版”通常能满足大概需求,但离“达到发表级别”往往还差几条细节修正。你把它当实习生来看待,给出明确的修改意见,它就能一件件改到位。这比你自己翻 ase 文档查 API 快得多。

3.3 实例三:让 GPT 实现含内变量的晶体塑性模型更新算法

这个实例稍微进阶一点,讲一个我近期在做的晶体塑性模型。模型里有滑移系,每个滑移系的解析剪切应力由施密德张量计算,塑性剪切应变率的演化由幂律公式控制,还要处理每个增量步内的牛顿迭代。

这种复杂逻辑在第一版提示词里没法一次到位。我的做法是分成三个阶段跟 GPT 对话。第一阶段,我让它搭框架:“请写一个晶体塑性的单晶积分类,包含以下方法:更新变形梯度、计算第二皮奥拉-基尔霍夫应力、更新滑移系阻力。暂不实现具体公式,用 pass 占位,只搭好类体系和交互接口。” 第二阶段,我把每个公式逐个给它,让它填空:“方法 update_slip_system 使用如下幂律方程:[公式],在更新阻力时需要计算累积剪切应变 [公式],请实现对应代码”。第三阶段才是联调,让它把主循环补全,跑通模拟。

这个递进式提问的好处是每一步的物理假设都被校准过,不容易跑偏。GPT 在第二阶段的实现里给了一个牛顿迭代求剪切应变增量的循环,迭代收敛条件写的是abs(dgamma_new - dgamma_old) < 1e-8。我检查之后把它改成了基于应力的余量判据,因为剪切应变增量在理想塑性区间可能变化很小,但应力误差还很大。这就是前面说的——物理把关还得靠自己,GPT 能给的只是高效的工具化实现。

这一段我没有贴完整代码,因为展开来太长了。但整个协作流程很值得参考:先框架、后公式、再调试,每一轮都让 GPT 解释关键代码的逻辑。这样几步走下来,一个以前要写两周的模型积分代码,我三天就搞定了主体部分,剩下的时间都花在物理验证和参数标定上。

4. 常见问题与排查技巧实录

4.1 GPT 给出的代码报错时,先查这三个地方

跟 GPT 合作编程,最常遇到的还是它生成的代码跑不过。我踩过太多坑之后,总结出一套排查顺序。

第一步看索引与维度。GPT 写代码特别喜欢用for i in range(len(...))这样的循环,一旦涉及多维数组,经常把shape弄混。我是怎么快速定位的?直接在报错信息后面加一句:“这种维度不匹配的问题,请检查每个数组的 shape,并在代码里加 assert 语句来保证维度正确。” 这一招立竿见影,GPT 会主动把断言加进去,后续调试就轻松了。

第二步看边界条件。计算材料力学程序经常有大量的条件分支,比如是否屈服、是否卸载。GPT 写的if条件经常把“大于等于”和“大于”搞混,或者漏掉== 0的临界情况。我的经验是,让 GPT 先给代码画一个逻辑分支的注释结构,再在关键条件处要求它注明物理含义。

第三步看数值发散。如果程序能跑,但输出的值全是 inf 或 nan,优先考虑时间步长和迭代容差。我会问 GPT:“如果数值发散,应该调整什么参数?请把时间步长、迭代容差设置为函数参数,并给出一组合理的默认值。” 这类问题通常出在塑性迭代不收敛或弹性矩阵求逆异常上,GPT 一般能给出合理的修正方向。

4.2 识别 GPT 的“幻觉函数”

GPT 会编造函数。它给出的代码引用了一个库,但那个库的某个方法根本不存在。这类问题最容易坑人,因为报错信息也看着正常。

我被坑得最惨的一次是它给我用了一个scipy.optimize.newton_krylov不存在的关键参数名,折腾了十分钟才发现是 GPT 记错了。从那以后我多了一招:拿到代码先不急着跑,把代码里每个第三方库的核心调用语句复制到官方文档或解释器里快速验证一遍。如果用的是常见库如 numpy、scipy、matplotlib,我还直接让 GPT 标注每个函数的来源、版本的兼容性要求。

一个更隐蔽的版本:GPT 用对了函数,但对函数行为理解错误。比如np.einsum求和下标写错,结果输出的是按元素乘积而不是张量缩并结果。这就要靠后面的物理验证来发现。

4.3 物理合理性验证不能省

代码能跑通,不等于结果是对的。做计算材料科学最危险的环节,恰恰是“代码看起来合理,但物理上是错的”。

我有一次让 GPT 写一个热力耦合的代码,它把热膨胀项的符号写反了,结果温度越高,材料反而收缩。这种 bug 在语法层面完全是合法的,但如果我当时直接拿运行结果去汇报,就闹笑话了。从那以后,我给自己定了一条规矩:任何新材料模型的代码,跑完第一步不是看最终结果,而是用一组手动能算的参数去验算。比如给定一组简单参数,材料在弹性阶段,输出应力是否等于弹性刚度矩阵乘以应变;再比如材料屈服后,应力是否按强化模量线性上升。这些手算验证的结果跟代码输出匹配了,我才放心。

把这个思路也塞进提示词里:“请给代码加上一个自测函数 demo_verification,用几组简单的解析解数据验证结果是否正确。” GPT 生成的验证函数可能不够全面,但至少是一个可用的起点,你可以再手动补充用例。

4.4 与 GPT 协作的“隐形坑”清单

这里我再列一下我实际踩过的高频坑,每一条都是真金白银换来的:

  • 单位不统一。提示词里没写,GPT 就敢把 GPa 和 MPa 混在一起用。我现在每条提示词都强制声明单位制。
  • 库版本不匹配。GPT 默认会给你最新版的 API 写法,如果你的环境的版本旧,兼容性就出问题。我会在提示词里加上“请使用 numpy 1.21.0 及以上版本兼容的写法”。
  • 不导出数据。它画完图就不管数据了。我通常在提示词里加“把结果数据保存为 csv 文件,放到指定路径”。
  • 缺少随机种子或初始条件设定。晶体塑性这类模拟对初始条件敏感,必须要求 GPT 写清楚状态变量的初始化,并且设定随机种子方便复现。
  • 中英文注释混杂。看起来很乱,倒是其次,更要紧的是注释不准确会误导后续维护。我一般指定“注释统一用中文,只注释物理含义和关键代码逻辑”。

5. 一些更“野”但好用的经验

写到这里,主体内容基本说完了,但我还想分享几个比较偏门的实用经验。这些都是在大量实战中慢慢总结出来的,未必能在教程里看到。

第一个是关于“让 GPT 写出穷举的测试用例”。我的习惯是让它不只生成实现代码,还要生成一个测试脚本,覆盖正常参数、边界参数、异常参数三类情况。在材料本构里,“异常参数”就包括弹性模量为 0、屈服强度为负、强化模量为 0。这些工况在真实标定中一定碰得到。写完测试脚本,我会挑其中两三个用例手动验算,其它交给机器跑。这样 GPT 给你挖的坑,至少能露出水面一半。

第二个是把 GPT 当同行来“讨论”,而不是“提问”。遇到一个不太确定的本构关系,我会把自己理解的物理机制发给它:“我理解这个模型是这么工作的,你看对不对?如果对,帮我按这个理解写代码。” 这样做有一个好处:GPT 会在你不准确的地方提出修正,相当于多了一个同行把关人。虽然它的物理水平有限,但总能帮我注意到一些被忽略的细节,比如边界条件的施加方式、数值奇异点的处理。

第三个是关于“持续跟踪版本化”。我的每个模型代码都有一个对比文件,记录“第一版 GPT 生成的代码”“我修改后的代码”“修改原因”。这不仅方便自己回看,而且当你把修改原因写清楚后,再拿给 GPT 继续迭代时,它给出的下一版会更贴合你的风格。这可能是最笨但也最有效的方法。我做过一次统计,用上这套协作方式之后,一个典型本构模型从需求到能跑的代码,平均时间从两周压缩到了三天左右,省出来的时间全都用在了物理验证和论文写作上。

我自己实际操作下来的体会是:提示工程的精髓,在于你要有自己的判断力,然后让 GPT 去执行那些“你其实会做、但做起来很繁琐”的活。反过来,如果你对物理模型本身就一知半解,GPT 能帮你的也有限。它能帮你把代码写得越来越快,但帮你把物理理解得越来越深,这件事它做不到。把它的输出当成一份精心排版过的草稿,把自己当成那个拍板的人,这套流程才能真正跑出价值。

系列后面我计划写提示词在相场模拟、有限元前处理、分子动力学后处理这些场景里的实战案例,也有不少坑可以聊。这篇就先到这里,如果你也在这个领域用 GPT 干活,欢迎对照着自己试试,遇到有意思的坑可以一起交流。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询