资讯动态

三维随机球形骨料+Abaqus+Python混凝土细观模拟全流程解析

发布时间:2026/10/20 7:49:20 来源:尧图企业网站定制
做混凝土细观模拟的人应该都对“三维随机球形骨料 Abaqus Python”这个组合不陌生。标题里的“环氧树脂基”看着像是物理试验里的透明基体做法但在数值模拟里它其实对应的是基体材料参数的选择问题。很多人第一步就被随机骨料生成卡住了手动建球根本不现实球数量多、尺寸小还要保证彼此不重叠、落在试件边界内靠鼠标点不出来的。用Python脚本生成骨料坐标再把几何和网格丢给Abaqus去算这是目前最稳也最省事的路线。这篇文章我会把整套流程拆开来讲随机骨料坐标怎么生成、体积率怎么校核、Abaqus脚本逻辑怎么搭、材料参数和界面怎么处理、常见的不收敛和布尔运算失败问题怎么排查。内容偏实操不会绕太多理论适合刚接触细观模拟、正打算复现三维随机骨料模型的同学。1. 细观模型到底在模拟什么1.1 为什么要把混凝土拆成骨料和基体宏观均质模型把混凝土当成一整块材料能算整体受力变形但算不了裂缝从哪儿开始、怎么穿透骨料、怎么沿界面扩展。真实混凝土是由骨料、砂浆、界面过渡区组成的细观层面的裂缝行为和宏观强度之间关系很密切。要研究尺寸效应、损伤模式、裂缝路径这些就得把混凝土重新拆成“骨料基体”的细观几何。细观模拟有二维和三维。二维建模快、算得快但其实就是薄片真相骨料卡在中间球假设变圆盘。三维能反映真实的粒间接触和裂缝立体扩展代价是几何复杂度和单元数量都上了一个量级。这篇文章说的就是三维球形骨料这条路线。1.2 球形骨料是简化但不是偷懒天然骨料形态千奇百怪但很多论文和工程模拟里都会先用球形近似因为球形有几个不可替代的优势球体在空间里任意方向旋转后仍然是同一个几何不需要考虑骨料朝向。球心和半径就能完整描述一个颗粒随机投放和重叠判断都变成了简单数学问题。球体几何的光滑性好网格划分和质量控制比多面体容易得多。界面过渡区厚度在球体外表面上可以均匀设置方便做cohesive界面单元或接触属性。如果你需要更真实的多面体骨料通常也是在球形骨料基础上用Voronoi切割、随机凹凸扰动等办法做出来。先把球形做通了再扩展多面体方案就有基础了。1.3 环氧树脂基在模拟里的定位做过物理实验的人应该知道环氧树脂可以做透明基体浇注在骨料周围固化了之后就能在加载时直接看到内部裂纹怎么萌生和扩展。这种“透明混凝土”思路很直观但物理试验周期长、试件制作难度高不能随便换骨料级配和体积率。数值模拟里的“环氧树脂基方案”就是把环氧树脂当作一种性能稳定的基体材料在Abaqus里用一组明确参数代替水泥砂浆。它的好处是材料接近线弹性脆性参数容易标定界面破坏规律比较清晰。很多模拟不是为了复现某一批真实混凝土试件而是为了做机理研究这时候用环氧树脂基做基准材料比用真实的混凝土材料更可控。在脚本里体现为基体材料换成一组环氧树脂的弹性模量、泊松比、抗拉强度、断裂能参数其他投放、网格、计算流程不需要变。2. 三维随机球形骨料生成的Python算法2.1 先算级配再算球数随机骨料的第一步不是直接随机坐标而是先根据级配曲线确定每种粒径区间需要多少颗球。最常用的是富勒级配或等效粒径法。以最大粒径20毫米、最小粒径4.75毫米的连续级配为例一般会分成几个粒径区间4.75至9.5毫米9.5至13.2毫米13.2至16毫米16至20毫米。每个区间的骨料体积占骨料总体积的比例可以由级配曲线积分得到。如果目标骨料体积率是45%试件尺寸是100毫米的立方体则骨料总体积为[ V_{agg} 100^3 \times 0.45 450000 \text{ mm}^3 ]每个粒径区间内的骨料体积占比假设为30%、35%、20%、15%那该区间的总体积就是骨料总体积乘对应百分比。用每颗球的体积 ( \frac{4}{3}\pi r^3 ) 一除就得到数量。这一步的关键是先算好每级球的数量投放时才能按数量去逐个生成。很多人上来就随机一堆小球最后体积率对不上就是因为没做级配预计算。2.2 随机投放策略先大后小是铁律三维随机骨料投放的核心有两个球不能超出边界球与球不能重叠。实际操作时还有一个隐性的第三点填充率要尽量接近目标值。如果保证不了体积率后面算出来的应力应变响应就缺乏代表性。我个人的习惯是先放大球再放小球。原因很直观大球体积大先把大球占好位置小球才能填在缝隙里。反过来先放一堆小球大球会频繁和已经存在的小球碰撞投放成功率会急剧下降试到几万次也投不进几颗。这个顺序问题直接决定投放能不能收敛。重叠判断用球心距离做判定[ d \sqrt{(x_i - x_j)^2 (y_i - y_j)^2 (z_i - z_j)^2} ]对两颗球半径 (r_i) 和 (r_j)需要满足[ d \ge r_i r_j gap ]其中 (gap) 是人为留的最小间隙。为什么要留间隙因为Abaqus布尔运算时如果两个球刚好相切或者几乎相切几何拓扑非常容易出问题。通常把gap设为最小粒径的1%到2%就够了不要留太大留太大会显著降低可投放空间。2.3 一套可以改着用的坐标生成代码下面这个脚本是我自己常用的简化版本。它只负责生成球心坐标和半径不依赖Abaqus环境任何能跑numpy的Python环境都能用。import numpy as np def generate_sperical_aggregate(sizes, domain_size(100.0, 100.0, 100.0), target_vol_frac0.45, gap0.05, max_trials5000): sizes: 单颗球半径列表已按从大到小排序后的数组 domain_size: 试件立方体的边长默认100mm target_vol_frac: 目标体积率 gap: 两颗球之间的最小间隙 max_trials: 每颗球的最大随机尝试次数 lx, ly, lz domain_size spheres [] total_vol 0.0 for r in sorted(sizes, reverseTrue): trial 0 placed False while trial max_trials: # 球心范围要预留半径和间隙 x np.random.uniform(r gap, lx - r - gap) y np.random.uniform(r gap, ly - r - gap) z np.random.uniform(r gap, lz - r - gap) ok True for (x0, y0, z0, r0) in spheres: dist np.sqrt((x - x0)**2 (y - y0)**2 (z - z0)**2) if dist (r r0 gap): ok False break if ok: spheres.append((x, y, z, r)) total_vol 4.0 * np.pi * r**3 / 3.0 placed True break trial 1 if not placed: # 单颗球投放失败通常说明体积率太高或空隙过大 print(fradius {r:.3f} mm not placed after {max_trials} trials) actual_vol_frac total_vol / (lx * ly * lz) print(factual volume fraction: {actual_vol_frac:.4f}, target: {target_vol_frac:.4f}) return spheres if __name__ __main__: # 示例先手动构造一组半径数据实际中应由级配计算生成 radii [] # 这里放从级配算出来的球半径列表 spheres generate_sperical_aggregate(radii) np.savetxt(spheres.csv, spheres, delimiter,)代码逻辑不复杂但要注意几个细节max_trials不能设太大也不能太小太大了死循环卡住太小了投放率低。一般每颗球试验2000次到10000次数据量大时可以额外加一个统计计数所有球累计尝试超过某次数就提前终止避免某颗小球卡住整个循环。球心坐标边界上预留了半径和gap这是为了让球完全落在试件内同时避免球贴边太紧影响网格质量。如果你想做周期性边界条件用的代表性体积单元这个边界预留就要改掉换成周期性投放逻辑也就是球的一部分可以伸出边界而在对面边界补回来这个后面单独说。2.4 体积率校核是进场检查生成完球心坐标第一时间不是进Abaqus而是先用一个独立脚本做体积率校核。把生成的所有球体积加起来除以试件体积看和目标值差多少。如果差超过1%就有问题。常见原因有两个一是投放失败球数太多体积率不够二是gap和边界预留把有效空间压缩太大导致个别大球投不进去。这时候不需要改整个算法先试着把gap缩小一点或者把球心边界范围从 (rgap) 改成 (r0.5gap)再看看体积率变化。只要体积率满足目标几何这一关就算过了。保存好的spheres.csv就是后面Abaqus脚本的输入文件。3. 从Python坐标到Abaqus几何和网格3.1 建模路线的选择球心坐标有了接下来把它变成Abaqus能算的模型。这一步有几种路线我简单对比一下路线优点缺点Abaqus Python API直接建模全自动修改级配方便脚本语法要熟悉调试略麻烦先用CAD软件画好再导入几何可视化方便大量球体导入极慢后期改动麻烦GUI里一个个手动建模直观超过50个球基本不现实绝大部分三维随机骨料模型球数都在几十到几百个用Abaqus Python API是唯一不折腾的选择。不需要把每个球做成独立草图和part那么笨可以先用Python生成一个主控脚本调用Abaqus的cae模块运行abaqus cae noGUIbuild_model.py脚本里用mdb.models[Model-1]访问默认模型然后循环读取spheres.csv逐个创建球体部件最后组合成试件。不建议在外部Python环境里安装了Abaqus库再去调用版本匹配和环境变量很容易出问题。3.2 球体部件的创建套路Abaqus脚本创建球体最常用的是草图旋转法先画一个以原点为中心、半径 (r) 的圆然后绕某条直径轴旋转360度。代码结构大概是这样的from abaqus import mdb from abaqusConstants import * def create_sphere_part(model_name, part_name, radius): model mdb.models[model_name] s model.ConstrainedSketch(name__profile__, sheetSize200.0) s.CircleByCenterPerimeter(center(0.0, 0.0), point1(radius, 0.0)) p model.Part(namepart_name, dimensionalityTHREE_D, typeDEFORMABLE_BODY) p.BaseSolidRevolve(sketchs, angle360.0)新建的球体part中心都在原点。后面装配的时候直接通过移动/平移把球心放到spheres.csv里记录的位置。主导脚本里会用很多part_name fSphere_{i}之类的循环命名球多的时候命名规则一定要清晰否则后期改材料赋值时找部件非常痛苦。3.3 基体与骨料装配布尔运算还是嵌入约束几何装配有两种主流的做法。第一种是“基体布尔减球”也就是先建立一个100毫米的立方体part再依次把那几百个球体从立方体里减掉形成带有空腔的基体。同时球体part继续保留作为骨料部件。这样基体和骨料在几何上是完美装配的后续可以直接在接触面上建立Tie约束或者插入Cohesive界面。这个做法几何真实但布尔运算在球数多、球间距小的时候容易失败。第二种是“嵌入约束”不切空腔直接把球体部件在装配里用Embedded Region嵌入基体。这种办法省掉布尔运算但骨料和基体之间没有真正的接触界面应力传递依赖嵌入约束的近似方式严格说不是真正的细观界面。如果只是算弹性阶段的总响应嵌入约束勉强够用想算界面开裂、裂纹沿骨料表面发展还是得用布尔运算。我自己的习惯是先用布尔减球跑通整个流程。如果布尔运算报了“几何退化”或者“部件自相交”之类错误再回头查是不是两台球间距太小或半径重叠而不是直接在错误状态下去硬算。布尔运算对几何要求很苛刻宁可让骨料体积率稍微低一点也要保证球与球之间留够间隙。3.4 环氧树脂基体的材料参数怎么给几何搞定之后材料参数就是一个典型的三相材料赋值问题基体环氧树脂类脆性材料弹性模量取3.0至4.0GPa泊松比0.35左右拉伸强度约60至90MPa断裂能低。在Abaqus里可以用Concrete Damaged PlasticityCDP模型或者Brittle Cracking模型。想算脆性开裂Brittle Cracking比CDP收敛更干脆但CDP能反映出峰后软化很多论文里也优先用CDP。骨料当作线弹性弹性模量40至60GPa泊松比0.2至0.24。骨料本身强度高细观模拟中不会率先破坏用线弹性够用了。界面过渡区可以单独建一层壳单元或cohesive单元也可以直接在接触设置中给界面属性。最省事的办法是暂时不给界面先把骨料和基体Tie在一起看基体开裂形态再考虑界面脱粘。要注意的是不同文献里的环氧树脂基参数差异很大自己做模拟时最好先用一组基准参数做参数敏感性分析不要直接照搬一个数值就当成真理。3.5 网格划分球形骨料最怕六面体球体和立方体之间的过渡是比较考验网格的。骨料和基体在布尔减掉之后基体空腔表面是球面很难生成干净的六面体网格。实际经验是直接用二次四面体单元C3D10虽然单元数量比六面体多但几何适应性非常强不容易在球面附近产生畸变。关键提示骨料外壳附近是应力集中区细化网格不要整块模型都加细应该用Mesh Controls里的Curvature Control或者布种时设置靠近球面的局部种子。通常做法是在基体part里球面周边定义多个Set通过Partition把基体切成小块再给球周区块用更小的种子尺寸。不做分区的话全局网格密度会要么太大算不动要么太小界面不够精确。网格尺寸选择上建议最小粒径内至少划分6到8个单元。最小粒径5毫米的话球面附近网格尺寸不要超过0.5至0.8毫米。骨料远处可以放大到2毫米节约单元量。4. 边界条件、加载方式与收敛控制4.1 单轴压缩的加载设置三维细观模型最常用的加载是单轴压缩和劈裂拉伸。先做单轴压缩时边界条件按常规方式设底部约束U1、U2、U3所有平动自由度。顶部约束U1、U2两个水平方向只留下U3方向位移加载。加载方式优先选位移加载不要选集中力。位移加载在峰值后的软化段更容易控制收敛集中力加载容易在出现第一条裂缝时直接发散。分析步用Static, General初始增量步可以设0.01最小增量步1e-8最大增量步0.1。如果发现峰后阶段无法收敛有两种调整方向一是把分析步改成Static, Riks弧长法它可以追踪荷载-位移曲线的下降段对付脆性断裂非常经典二是转到Abaqus/Explicit显式动态分析显式算法对接触和材料断裂的鲁棒性远高于隐式代价是计算时间更长必须加质量缩放。4.2 边界条件要不要做周期性很多细观模拟的目标是得到代表体积单元的等效力学性能这时边界要用周期性边界条件。Abaqus的周期性边界条件可以通过在对应的平行面之间建立线性约束方程Equation Constraint来实现也可以在脚本里自动生成。用Python批量添加约束方程并不难但门槛比普通边界高不少。如果没有做均匀化等效性能的需求只是做单块试件裂缝扩展的机理研究用固定边界条件完全够。但要注意固定边界会带来表面效应试件边界的骨料和基体比中间区域更容易受约束影响。为了减小这种影响试件尺寸至少要大于最大骨料粒径的3倍主流论文里一般取5倍以上。比如最大粒径20毫米试件边长至少100毫米以上。4.3 骨料和基体界面的绑定方式如果不做界面脱粘骨料外表面和基体空腔内表面用Tie约束绑在一起就行。Abaqus里Tie的注意点从面和主面的网格硬度有差异时把刚度大、网格粗的面设为主面。骨料相对基体刚度大通常把骨料表面设为主面。球面曲率大绑定区域用默认的几何容差可能不够需要设置position tolerance稍大一点否则有些节点对识别不上。Tie约束是线性的骨料和基体之间没有摩擦、没有剥离不能模拟骨料被挤出或脱空。要做界面脱粘就得用Cohesive接触属性或者基体与骨料之间建Cohesive单元。接触属性的参数包括法向刚度、切向刚度、最大法向应力、最大切向应力、断裂能。没有实验数据时界面刚度可以取基体弹性模量除以界面厚度来估算界面厚度取0.1至0.5毫米。Cohesive参数比Tie参数多但能模拟界面微裂纹先产生再贯通到基体中的现象这在真实混凝土里非常常见。4.4 后处理看什么指标细观模型的后处理重点不是只看一个von Mises云图要关心的量有基体损伤变量。Abaqus的CDP模型里可以输出DAMAGEC、DAMAGET看受拉区损伤分布。SDEG单元的刚度退化。如果用了cohesive单元SDEG代表界面刚度退化程度值从0到1接近1说明界面已经失去承载能力。裂纹形态。可以通过绘制最大主应变云图或者提取损伤变量超过阈值的单元集合来看裂缝走向。荷载-位移曲线。这个决定了材料的宏观强度和韧度。建议在Step模块里把输出间隔减小一点尤其在中后期每5个增量步输出一次否则最后想细看裂缝扩展时输出点太稀疏完全看不出连续性。5. 常见问题与排查技巧实录5.1 骨料投放体积率死活上不去如果你发现actual volume fraction离目标值差了一截先别怀疑算法按这个顺序排查检查投放顺序是不是从大到小。这个原因占了六成以上。检查gap值是不是太大。有些代码把gap固定为0.5毫米对最小粒径4.75毫米来说单颗球占据的排斥空间差不多是球半径的20%体积率肯定下去。检查球心边界有没有多预留一层空隙。如果边界范围设成 (r gap) 到 (L - r - gap)球心活动区域缩小得比想象中多尤其小试件更明显。检查目标体积率本身是否合理。三维随机球形骨料在普通随机投放算法下体积率超过50%以后会越来越难试到几十万次也未必能投满。如果文献要求55%以上通常建议改用初始密排或者振动密实算法。排查完这些再用散点图把球心位置画出来看一眼能发现很多脚本日志里看不出来的空间分布问题。5.2 Abaqus布尔运算失败几何退化怎么办布尔运算时报错是最常见的劝退点。我遇到过的典型错误包括“part instance cannot be boolean subtracted due to topology”和“set contains invalid entities”。原因基本集中在几个方面球体之间实际重叠了只是体积率校核时没看出来。要检查CSV里的球心距和半径关系。球体和基体表面刚好接触没有间隙。Abaqus对相切面的布尔处理非常敏感相切情况下切掉的空腔会产生退化边。多个球同时相交相交区域太碎几何清理跟不上。解决方案生成球心坐标时强制加一个最小间隙按我前面说的方法留gap或者在做布尔减的时候把每个球半径临时缩小0.3%至0.5%让球体和球体之间的接触完全断开。这个“缩球”操作对网格影响非常小但对布尔运算成功率帮助极大。如果布尔运算还是失败另一个思路是换Embedded Element绕过空腔建模。虽然界面力学响应弱一些但至少能先把材料参数和加载逻辑跑通等确认整体流程没问题后再回来处理布尔几何。5.3 静力计算总是不收敛不收敛几乎和骨料数量无关而是和开裂后的非线性有关。混凝土类脆性材料一旦局部开裂应力会在损伤单元附近重新分布隐式静力分析每一增量步都在调整迭代平衡很容易发生“局部失效 → 平衡丢失 → 增量步分裂 → 再失效”的死循环。几种处理办法改用Static, Riks弧长法追踪下降段。在CDP参数里增加较小的粘性系数比如取值 0.0001不要超过0.0005这个系数相当于给损伤演化加了一点粘性阻尼能显著改善收敛但对峰后应力结果影响不大。检查过约束。有没有同时对同一个节点施加多个互相矛盾的约束或者Tie主从面设置有无方向问题。最后再考虑显式分析。Explicit配合C3D10R单元材料用CDP虽然计算时间可能是隐式的三到五倍但很少因为开裂而发散。网格畸变也是不收敛的一个隐藏原因。球面附近如果出现过度扭曲的四面体局部应变会异常大单元在开裂前就先畸变。检查方法是看变形后网格云图中最大变形区域是不是集中在少数几个异常单元上。5.4 单元数和内存失控三维细观模型很容易把单元数堆到几十万甚至上百万。以100毫米立方体、最小骨料粒径4.75毫米、基体网格1毫米为例最终单元数随便就能到30万以上隐式计算时内存占用接近10GB。如果不做控制普通笔记本是跑不动的。几个压计算量的手段用二级配代替四级配去掉最小粒径那级骨料单元量会大幅下降。把试件尺寸缩小只要保证最大骨料粒径3倍以上的最小尺寸参数规律不会变。骨料内部网格可以适当放大。骨料被设为线弹性内部应力梯度小不需要和基体一样密。基体网格采用渐变密度球面周边加密、远离球面区域放松。并行计算开启MPI四核到八核的提升基本是线性的。我个人的经验是先做一个小模型比如50毫米立方体、最大粒径10毫米球数只放三四十颗先把整个Abaqus脚本流程跑通。一次成型直接堆大模型的教训是脚本错一个字母几何错一整批浪费几个小时口算都得重来。做细观模拟这行工作流顺不顺往往不取决于你多会调一个材料参数而是取决于能不能稳定地从随机坐标走到最终云图。把投放、建模、网格、加载、后处理每一步都做成可以手动检查的小模块比追求一次性全自动要可靠得多。刚开始跑的时候宁可每一步多看一眼输出文件也别让脚本自动连轴转。等这些坑都踩过一遍后面的路就顺了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑