做多孔介质建模的人,迟早会被COMSOL里手动摆放颗粒这件事折磨到怀疑人生。一张1mm见方的岩石切片,放两三个圆没什么感觉,放到四十个就足以让人想砸鼠标,更别提颗粒位置、粒径分布和孔隙率根本没法交代。我后来把整套流程搬到了COMSOL+MATLAB联合建模上:MATLAB负责随机几何的生成与批量控制,COMSOL负责导入几何、设定物理场、网格剖分和求解。这套组合解决的不只是时间问题,而是把“随机多孔介质”从一个不可复现的手工图,变成了可参数化、可批量扫描、可追溯种子编号的标准化流程。
这篇内容适合正在做渗流模拟、燃料电池多孔电极、地下水污染迁移、相变材料泡沫骨架这一类工作的研究生和工程师。下面从几何生成方案选型、MATLAB端核心算法、数据导入通路的取舍,到COMSOL里的物理场与网格设置、批量扫参和踩坑排查,按我实际跑通的顺序讲一遍。
1. 先搞清楚要解决什么问题:应用背景与程序化建模的必要性
1.1 多孔介质模型到底在模拟什么
多孔介质模型的覆盖范围比想象中大得多。油气藏中岩石的孔隙网络决定渗透率和含油饱和度,燃料电池气体扩散层需要平衡气体输运与排水,电极里面的多孔结构决定电化学反应有效面积,泡沫金属作为相变材料支架时既要有高孔隙率又要保证机械强度。这些场景的共性就是:孔隙结构对宏观性能有决定性影响,而孔隙结构本身具有强烈的随机性和尺度跨度。
COMSOL里处理多孔介质问题通常分两条路。第一条是宏观均质路线,直接把整个区域当成多孔介质,用Darcy定律或多孔介质传热模块,输入一个平均渗透率和孔隙率就算完了。第二条是微观显式建模,把颗粒和孔隙的几何边界真实建立出来,在每个孔隙里直接求解流动方程,再从计算结果反算等效宏观参数。后者就是我们说的“生成多孔介质模型”,也是本篇的核心内容。
既然要显式建模,几何就必须描述到颗粒级别。颗粒多、随机性强、需要参数化调整,这三个要求叠加起来,手工作图基本就是死路。
1.2 手动画到崩溃的三个具体原因
手工建模的问题不是“慢”这一个维度,而是三个维度同时出问题。
第一是随机性无法控制。手工摆放颗粒时,人的眼睛会本能地让颗粒“看起来均匀”,但真实砂石或粉末堆积恰恰是带随机涨落的。你手动排出来的模型,往往均匀得像棋盘一样假,用来做统计分析本身就失真。
第二是孔隙率无法定量。COMSOL里手工画几十个圆,每个圆半径设多少、圆心放哪,全凭直觉,做完根本不知道自己做的模型孔隙率是多少。要想让孔隙率精确落在0.35或0.48,手算是算不出来的。
第三是参数扫描完全没有希望。你要研究孔隙率从0.3到0.6之间渗透率怎么变,手工建模就得建七八个模型,每个模型几十个颗粒,工程量直接爆炸。而用脚本生成,一个循环就能把目标孔隙率跑完,还能按不同随机种子多跑几次取平均。
所以程序化建模不是“优化”,而是这类研究的前置条件。
2. 几何生成方案选型:四条路怎么选
多孔介质几何生成不是只有随机堆圆一种办法,不同材料微结构对应的生成逻辑完全不同。我按自己的使用频率排一下。
2.1 随机颗粒堆积:最通用的起点
随机颗粒堆积法是最容易上手的方案。原理就是在计算区域内随机放置圆或球,保证颗粒之间不重叠,通过颗粒数量和半径分布控制孔隙率。它适合模拟砂石颗粒、催化剂填充层、混凝土骨料这类粒状材料,也是做渗透率反算时最稳定的几何来源。
二维情形下就是一个矩形域里放N个圆,判断条件只有一条:任意两个圆的圆心距离必须大于两个半径之和,再加一点安全间隙。三维就是判断球心距离,逻辑完全一样,只是生成密度更高时更考验效率。
这个方案最大的优点是孔隙率容易控制和测量。二维孔隙率就是
φ = 1 - (πΣr_i²) / L²
圆半径、颗粒数量、区域边长都是显式参数,调整起来非常直接。所以如果你刚接触COMSOL+MATLAB,我强烈建议从这个方案开始。
2.2 Voronoi剖分:泡沫和晶粒结构的捷径
如果你想模拟泡沫金属、海绵、晶粒或三维纤维骨架,随机颗粒堆积就不合适了,因为这类结构的特征是连续骨架加连通孔隙,而不是孤立颗粒加孔隙。
Voronoi剖分的思路是:先在区域内随机撒点,然后用泰森多边形把区域切成许多多边形单元,保留多边形边界作为骨架,或者反过来把多边形内部视为孔洞。MATLAB里直接用voronoin函数就能得到顶点和单元信息,二维实现很快。
但这个方案的坑也不少。区域边缘的多边形会被边界切掉,需要手动裁边;撒点太均匀会让结构看起来像蜂巢,缺少随机感;孔隙率控制也不如随机颗粒那么直接。我一般只在对泡沫结构有明确需求时才用。
2.3 四参数随机生长法与CT重建
更贴近真实岩石的是四参数随机生长法,文献里常叫QSGS。这个算法的核心是:先在网格上按成核概率随机撒“种子”,然后每个种子以一定的方向概率向相邻格子生长,最终形成复杂的连通孔隙网络。它可以模拟具有多相、多尺度特征的地质材料,生成效果比随机颗粒更“像”真实岩石。
不过QSGS生成的几何是像素或体素级的,直接导入COMSOL会带来大量锯齿边界,布尔运算和网格剖分都非常痛苦。我的做法是先生成像素矩阵,提取孔隙和骨架的边界坐标,再降采样后用DXF或坐标序列导入,骨架边界尽量平滑。CSDN上很多复现论文的帖子也提到这个问题,实测下来先提取再导入确实比直接丢位图稳得多。
如果你手里有真实样品的CT扫描数据,那就走CT重建路线:把切片序列读入MATLAB,做二值化、去噪、孔隙连通性分析,再提取轮廓导入COMSOL。这条路最真实,但数据处理量最大,一个模型有可能是几百万个体素,几何导入和网格剖分都要做好心理准备。
2.4 怎么根据研究目标做选型
选型不只看材料像不像,更要看后续能不能算。我列一张实际对比表。
| 方案 | 适合场景 | 孔隙率控制 | COMSOL几何友好度 | MATLAB实现难度 |
|---|---|---|---|---|
| 随机颗粒堆积 | 砂石、颗粒填充、催化剂床层 | 容易 | 高 | 低 |
| Voronoi剖分 | 泡沫金属、晶粒结构 | 一般 | 中 | 中 |
| QSGS | 复杂岩石、多相介质 | 中等 | 低 | 中高 |
| CT重建 | 真实岩心、生物组织 | 几乎不可调 | 低 | 高 |
一句实在话:如果只是想把渗透率、孔隙率、粒径影响这几个宏观规律算明白,随机颗粒堆积是性价比最高的起点。其他方案等你对COMSOL几何操作足够熟练之后再上,不然会同时栽在几何和网格两个坑里。
3. MATLAB端先把几何做对:不重叠随机颗粒核心算法
这一步是整个流程的基石。几何没生成好,后面导入COMSOL、布布尔运算、剖网格全是废的。我不只给代码,也解释为什么这么写。
3.1 确定性随机:给模型加个种子
随机模型的复现性是很多新手忽略的事。我今天跑出一个渗透率0.85D,明天重新运行脚本结果变成0.92D,如果每次都在变,你根本没法排查问题,也没法在论文里给出可复现的数据。
解决办法是固定随机数种子:
rng(2024);只要种子固定,后续所有随机数序列就固定了。同一套代码在不同机器或不同时间运行,生成的颗粒位置完全一致。这在调试和审稿时都非常重要。我的习惯是以年份或日期做种子,每个工况分配一组种子,例如孔隙率0.35跑seed 1到5,孔隙率0.40也跑seed 1到5,这样不同工况之间有合理的随机差异,又有可对照性。
3.2 不重叠判定与安全间隙
生成不重叠随机圆的关键,不是随机生成,而是“生成后立刻检查再决定要不要”。我用的循环逻辑是:先随机产生一个候选圆心,然后与所有已放置的颗粒比较距离,如果重合就重新生成,直到成功放下。
半径分布我推荐用正态分布再加最小值下限,否则随机出来的负数半径会直接摧毁你的模型:
rng(2024); L = 1; % 计算区域边长,建议与COMSOL里的单位保持一致(这里是m) N = 40; % 目标颗粒数 r_mean = 0.06; % 平均半径 r_std = 0.015; % 半径标准差 r_min = 0.025; % 最小半径 r = max(r_mean + r_std*randn(N,1), r_min); r = sort(r, 'descend'); % 先放大的颗粒,小的放在最后更容易塞入空隙 gap_ratio = 0.08; % 安全间隙系数,建议0.05~0.10 pos = zeros(N,2); for i = 1:N margin = 1.05 * r(i); % 把颗粒圆心限制在区域内,避免切边 placed = false; while ~placed cand = [rand*(L-2*margin)+margin, rand*(L-2*margin)+margin]; placed = true; for j = 1:i-1 if norm(cand - pos(j,:)) < r(i) + r(j) + gap_ratio*r(i) placed = false; break; end end end pos(i,:) = cand; end porosity = 1 - sum(pi*r.^2)/L^2; fprintf('实际孔隙率:%.4f\n', porosity);这里有三个细节要说明白。
第一个是margin = 1.05*r(i)。如果不加这个边界限制,颗粒圆心可以落在边缘,圆会超出计算区域,被边界切断,直接影响流动通道的连通性。加5%的余量是为了让颗粒完整地待在区域内,避免与边界相切或相交。
第二个是安全间隙gap_ratio。判断重叠的最小距离不只是两半径之和,还要额外加一点间隙。这个间隙在几何上代表颗粒之间的最小孔喉宽度。如果你设0,两个颗粒会刚刚好相切,COMSOL在布尔运算时可能因为浮点误差而判定重叠,网格剖分时那个切点附近也容易产生退化单元。我实测下来,gap取最小半径的5%到10%比较稳定。
第三个是sort(r,'descend')。先放大颗粒后放小颗粒,可以让空间利用率更高。如果你反过来先放小颗粒,后面的大颗粒经常会找不到位置,算法会陷入无限循环。
3.3 孔隙率目标与评估
代码跑完会打印实际孔隙率。你会发现它通常和你的理论目标有偏差,这是正常的。想调节孔隙率,优先改颗粒数量N,其次改平均半径r_mean。不要靠无限调小gap去凑孔隙率,因为gap直接影响后续网格质量,太小了网格剖分必挂。
还有一个评估技巧:算一下最小圆心距与对应半径和之差,这就是整个模型里最窄的孔喉宽度。COMSOL网格剖分时能不能收敛,很大程度上就取决于这个最窄处。你可以直接打印出来:
gap_min = inf; for i = 1:N for j = i+1:N gap_min = min(gap_min, norm(pos(i,:)-pos(j,:)) - r(i) - r(j)); end end fprintf('最小孔喉宽度:%.6f\n', gap_min);这个值如果小于颗粒半径的2%,你就要回去调gap_ratio了。
4. 从MATLAB到COMSOL的三种通路,我推荐这么搭
几何在MATLAB里生成好之后,接下来要解决“怎么把它弄进COMSOL”。我试过三种通路,分别说下优缺点和适用场景。
4.1 LiveLink for MATLAB:一管到底的最优选
COMSOL官方有一个LiveLink for MATLAB模块,安装时勾选上,就可以在MATLAB里直接创建模型、加几何、设物理场、求解、取结果。有了它,前面生成的坐标可以直接通过API喂给COMSOL,根本不需要中间文件。
基本思路是:
model = mphstart(2036); % 创建矩形计算区域 model.component('comp1').geom('geom1').create('rec1','Rectangle'); model.component('comp1').geom('geom1').feature('rec1').set('size', [L L]); % 逐个创建圆颗粒 for i = 1:N cirName = sprintf('cir%d', i); model.component('comp1').geom('geom1').create(cirName, 'Circle'); model.component('comp1').geom('geom1').feature(cirName).set('r', r(i)); model.component('comp1').geom('geom1').feature(cirName).set('x', pos(i,1)); model.component('comp1').geom('geom1').feature(cirName).set('y', pos(i,2)); end上面是示意代码,不同版本API细节会有差异。我的经验是:先手动在COMSOL里做一遍完整流程,再研究LiveLink的帮助文档,把操作翻译成脚本,而不是凭空写API。
这条路最大的优势是完整自动化。几何、网格、物理场、求解、结果导出全部在一个MATLAB脚本里,批量扫参的核心就是靠它。缺点是需要额外安装插件,而且API有学习成本。
4.2 用DXF导入:轻量稳当,适合小批试验
如果你不想碰LiveLink,或者只是先试一两个模型,DXF导入是最省事的方式。DXF是CAD领域很成熟的二维交换格式,COMSOL可以直接导入圆、线段、样条线等基本图元。
MATLAB生成DXF文件也很简单,一个标准的DXF圆实体示例是这样写的:
function writeCirclesDxf(fname, pos, r) fid = fopen(fname, 'w'); fprintf(fid, '0\nSECTION\n2\nHEADER\n0\nENDSEC\n'); fprintf(fid, '0\nSECTION\n2\nENTITIES\n'); for i = 1:size(pos,1) fprintf(fid, '0\nCIRCLE\n8\n0\n10\n%.15f\n20\n%.15f\n30\n0\n40\n%.15f\n', ... pos(i,1), pos(i,2), r(i)); end fprintf(fid, '0\nENDSEC\n0\nEOF\n'); fclose(fid); end注意DXF里组码10、20、30分别是圆心的x、y、z坐标,40是半径。调用writeCirclesDxf('circles.dxf', pos, r)就会生成一个包含所有圆的DXF文件,然后COMSOL里文件→导入→DXF直接拉进来。
这个通路的好处是直观,几何文件能保留下来随时查看,适合小规模验证。坏处是每个圆导入后都是独立几何对象,颗粒数量一多COMSOL几何树会非常臃肿,布尔运算也会明显变慢。我建议不超过一两百个圆时用DXF,再往上就走LiveLink。
4.3 版本兼容与单位对齐
无论走哪条通路,都要先过两关:版本兼容和单位对齐。
LiveLink对MATLAB版本有明确要求。安装COMSOL时如果提示找不到MATLAB,往往是因为MATLAB版本不在支持列表里。建议装COMSOL之前先查官方兼容性矩阵,别等装到一半才发现不认。
单位对齐的坑更隐蔽。COMSOL默认几何长度单位通常是米,但很多人习惯在MATLAB里用毫米甚至微米。假如你在MATLAB里生成了边长1000的模型,原意是1000微米,导入COMSOL后被当成1000米,整个几何体大得离谱,后面网格剖分轻则奇慢,重则直接报错。我的习惯是MATLAB和COMSOL全用米制,颗粒半径写成0.00006这种,虽然数字不好看,但单位永远不出错。
5. COMSOL端从几何到求解:物理场、边界、网格一套走
几何导入只是开始,后面才是真正见功夫的地方。
5.1 先理解“差集”而不是“并集”:颗粒固体与流体域怎么分
很多初学者导入圆之后习惯性做并集,结果越做越乱。这里的关键是区分固相和流体相。
我们的目标是模拟流体在颗粒间的孔隙里流动。因此几何上要有两块东西:矩形计算区域是总的流体与固体的占位空间,圆形颗粒是固体骨架。最终参与流动计算的应该是矩形减去所有圆得到的孔隙区域,而不是圆本身,也不是所有圆合并在一起。
在COMSOL几何节点里的标准操作是:先建一个矩形域rec1,再导入所有圆cir1到cirN,然后新建一个“差集dif1”节点,把rec1作为被减对象,所有圆作为减去对象。这样得到的差集域才是孔隙空间。圆本身作为固相,可以保留下来用于传热计算或结果可视化,在流动物理场里不参与求解。
如果几何是DXF导入的,同样的逻辑:矩形和圆都是独立的几何图元,在几何节点里手动拖入“差集”节点,选择矩形和圆,构建几何,搞定。
这个步骤一旦搞反,后面所有物理场和边界条件全部白设。
5.2 物理场怎么选:显式几何用蠕动流,宏观均质才用Darcy
接下来是物理场选择,这一节能劝退不少新手。
如果你已经建了显式孔结构,就不应该再用Darcy定律去求解。Darcy定律是体积平均方程,它的输入是宏观渗透率,前提是已经忽略了孔隙具体形貌。你既然把每个颗粒都画出来了,就不要再给孔隙区域赋一个渗透率,否则逻辑上自相矛盾。
正确的做法是:在显式孔隙空间里求解流动方程。COMSOL里有专门的“蠕动流Creeping Flow”模块,或者用单相流里的“层流Laminar Flow”。蠕动流本质是Stokes方程,忽略了惯性项,适用于雷诺数远小于1的渗流场景。对于岩石、砂层这样的微渗流,Re通常都在1e-3量级以下,蠕动流就是最稳的选择。如果局部流速较高、Re接近甚至超过1,再用完整层流方程,保留对流项。
那Darcy定律什么时候用?当你做的是宏观均质模型,把多孔材料看成一个连续体时,才用Darcy或多孔介质流动模块,输入等效渗透率和孔隙率。
简言之:微观显式结构配蠕动流/层流,宏观均质模型配Darcy。千万不要混搭。
5.3 边界条件与压力驱动渗流的具体设定
以计算绝对渗透率为目标时,标准做法是设置压力驱动的单相稳态流。
左右两侧设为压力边界:入口给一个低压差,比如P_in = 100 Pa,出口P_out = 0 Pa。上下边界设为对称或壁面均可,如果目标是模拟无限大介质中的代表性体积元,更严谨的做法是设周期性边界条件,让上下两侧的流动满足周期对称。
颗粒边界设为无滑移壁面,这符合实际固液界面的物理条件。中间孔隙区域选用蠕动流物理场。
这里要特别提醒:压差不是越大越好。压差太大,孔隙喉部流速可能进入非线性区,Re增加,偏离Stokes假设,求解发散的风险也会成倍上升。我一般先用1 Pa或10 Pa试跑,收敛后再逐步加压差,直到确认流动仍处于线性区。
5.4 网格设置与渗透率反算
网格剖分是多孔介质模型最容易卡住的环节。多孔介质几何的特点是微小的颗粒间隙夹杂在大尺度单元之间,网格尺寸跨越很大。
我的网格策略很简单粗暴:最大单元尺寸取最小颗粒半径的1/3到1/5。整体网格用自由剖分三角形,在颗粒边界附近自动加密。COMSOL默认的“较细化”级别很多时候够用,但你必须先确认最小孔喉处至少有几层网格,否则那里的流速算不准。
网格剖分完成后,求解得到速度场和压力场,然后在模型结果里积分出口边界上的体积流量Q。有了Q,就可以用Darcy定律反算等效绝对渗透率:
k = (Q · μ · L) / (A · ΔP)
其中μ是流体动力黏度,L是流动方向上的模型长度,A是垂直流动方向的截面积,ΔP是进出口压差。
举个例子:模型长度L=1e-3 m,截面积A=1e-6 m²(二维模型取宽度×单位深度),μ=1e-3 Pa·s,ΔP=100 Pa,积分得到Q=1e-10 m³/s,则
k = 1e-10 × 1e-3 × 1e-3 / (1e-6 × 100) = 1e-12 m²
1e-12 m²正好约等于1达西(D)。这个数量级和很多实际砂岩的渗透率非常接近。
6. 批量扫参:孔隙率与渗透率关系的自动化提取
几何生成和单模型求解都跑通之后,批量扫参就水到渠成了。这也是整个联合建模真正发挥威力的地方。
6.1 一次跑一个样本的陷阱
多孔介质模型有显著的随机性。你固定孔隙率0.4,只生成一组颗粒,算出一个渗透率,再生成另一组颗粒,算出来可能相差20%甚至更多。这是因为随机颗粒排列导致的孔喉连通性差异很大,个别样本可能恰好存在一条贯穿大通道,渗透率就显著偏高。
所以科学的做法是对每组参数跑多个随机样本,取统计值。一般至少5个种子,论文里要求高的会跑到10个以上。渗透率在样本间的分布往往接近对数正态,所以我习惯取log后的均值再换算回来,避免个别极端样本把平均值拉偏。
6.2 多构型循环与平均值
一个可用的批量脚本框架是:
poro_list = 0.30:0.05:0.60; results = []; for poro_target = poro_list k_samples = []; for seed = 1:5 rng(seed); [pos, r] = generateParticles(poro_target); % 根据目标孔隙率生成颗粒 k_val = runDarcyModel(pos, r); % 导入COMSOL并求解 k_samples(end+1) = k_val; end k_geo_mean = exp(mean(log(k_samples))); results(end+1,:) = [poro_target, k_geo_mean]; end这里generateParticles和runDarcyModel需要你自己封装起来。前一个函数就是我们第3部分写的生成逻辑,后一个函数封装了LiveLink从建模型到积分的完整过程。
跑完循环后把results存成CSV,用MATLAB随便画个散点图,你能看到孔隙率增大时渗透率如何非线性的上升。通常孔隙率从0.3提到0.6,渗透率可能提升一到两个数量级,比线性直觉激进得多。
这里有一个重要经验:用LiveLink批量跑的时候,每跑完一个模型就把模型句柄清理掉,不然内存会像滚雪球一样膨胀。尤其当颗粒数量多、网格细的时候,COMSOL模型对象的开销很大,循环几十次之后MATLAB可能直接卡死。另外建议每个工况单独保存一个.mph文件,方便后续复盘某个特定样本的几何和网格。
7. 实测坑与排查思路:几何、单位、网格、求解逐层拆
下面这些坑都是我实际踩过并且花时间排查过的。把排查链路写出来,你遇到类似问题时可以直接照方抓药。
7.1 颗粒重叠导致的几何退化
症状:COMSOL构建几何时报错,或者布尔差集生成的结果残缺不全;网格剖分时提示“几何退化”。
排查链路:先回到MATLAB算一下最小圆心距与半径和之差。如果这个差值是负数或者接近0,说明存在重叠或相切。再把重叠的颗粒对画出来,确认问题后调整gap_ratio和margin,重新生成。
这里有个容易忽略的点:即使你在生成时加了gap,也可能因为半径排序后调整了颗粒编号,导致某次随机碰到极小间隙。建议在生成函数最后再加一道全量检查,把所有颗粒对的最小间距都跑一遍,确保没有漏网之鱼。
7.2 DXF单位错乱
症状:导入COMSOL后,几何尺寸完全对不上,颗粒直径变成几十米或者小到看不见。
排查链路:DXF文件本身不强制写单位,COMSOL导入时会按当前几何节点单位解释。你matches用毫米生成DXF,但COMSOL默认几何单位是米,尺寸就放大1000倍。解决办法有两种:一是在COMSOL全局参数里把几何单位明确设为与DXF一致;二是在MATLAB导出时就换算成米制坐标,一劳永逸。我推荐第二种,因为后续物理场设置、结果解释都不用再纠结单位。
7.3 求解发散与网格畸变
症状:Stokes或层流求解到一半不收敛,或者报“找不到一致初始值”。
排查链路:先检查网格最小尺寸。如果最小孔喉处只有一层网格甚至没有网格,速度梯度根本捕捉不到,必然发散。解决办法是加密颗粒边界附近的网格,或者回到几何生成阶段增大最小间隙。
如果网格没问题,把入口压差从100 Pa降到1e-3 Pa再跑。Stokes方程是线性的,很低的压差下几乎一定收敛。如果低压力下正常、高压力下发散,说明局部雷诺数过高,已经不再满足蠕动流假设,这时候要么改用层流模块带惯性项,要么缩小模型尺度。
另外排查一下模型是否被颗粒隔断成了不相连的区域。如果某块孔隙空间只有入口没有出口,或只有出口没有入口,压力方程在孤立域上会出问题。判断连通性可以读入MATLAB做二值连通域分析,也可以用COMSOL里直接看几何错开情况。
7.4 边界被切断
症状:颗粒恰好横在入口边界或出口边界上,导致进口被固体堵死,流量严重偏低。
排查链路:检查生成逻辑里的margin设置。颗粒圆心到边界的最短距离至少要大于1.05倍颗粒半径,否则就可能与边界重叠或被边界切割。如果确实需要边界处有颗粒来体现真实堆积效果,那就专门做边界处理,比如把边界上的颗粒真实保留,并确认流动通道仍然连通。多数渗流研究中,代表性体积元的边界都要避免颗粒横切,以减少边界条件造成的非物理效应。
多做一步:每次生成完几何后把颗粒位置画出来,目测检查一遍边界有没有问题。视觉检查虽然土,但往往能发现数值检查漏掉的异常。
最后再分享一个实操小技巧。我刚跑通这套流程的时候,习惯把孔隙率、最小孔喉宽度、渗透率、种子编号一起存进文件名,比如phi0.35_gap0.004_seed2_k1.12D.mat。一开始觉得多此一举,后来发现当样本量开到几十个以后,这个命名方式救了我无数次。反查异常结果时,看到文件名就知道这个模型是怎么生成的,不用重新跑一遍脚本。
整个COMSOL+MATLAB生成多孔介质模型的流程,说白了就是把几何交给脚本、把计算交给COMSOL、把重复交给循环。几何阶段的微小疏忽,到了网格和求解阶段都会被无限放大。所以我的建议是:第一步先在不重叠生成、最小孔喉控制、单位统一这些基础细节上多花时间,把地基打牢,后面批量扫参和数据分析就是顺水推舟的事。