我最早意识到这个问题,是在做一个小半径隧道开挖模型的时候。模型跑完后洞周云图看起来也挺正常,sxx、syy都有各自的分布,但真正到写报告的时候我卡住了:设计方要的是“洞壁围岩的径向应力和切向应力”,不是直角坐标下的sxx、syy。FLAC 3D默认在笛卡尔坐标系里输出所有应力和位移分量,可圆形巷道、钻孔、竖井这类问题,工程上最关心的量都是沿着半径方向和切线方向定义的。从那一刻起我才认真把“FLAC 3D极坐标下应力与位移”这件事从头捋了一遍,这里面的坑比想象中多,但捋清楚之后,很多后处理工作会变得非常顺手。
这篇文章写给谁?主要是在用FLAC 3D做隧道、巷道、桩基、基坑或者弧形结构分析的人。你已经会建模、会跑计算,但可能和我一样面临一个问题:模型结果有了,可该怎么把直角坐标下的应力和位移正确地转换到极坐标里?这篇文章会讲清楚坐标转换的数学原理、FLAC 3D数据提取的三种可行方案、画极坐标曲线的实操经验,以及我在处理弧形堤坝位移监测数据时踩过的一些坑。我不打算讲太多教科书理论,尽量多给能直接上手用的东西。
1. 圆形结构分析为什么绕不开极坐标视角
1.1 洞室围岩的径向应力和切向应力才是设计要的东西
在地下洞室、深埋巷道这类问题里,应力场在洞室周围会发生重分布。我们可以想象在洞壁上取一个微元体,这个微元体的一对面垂直于半径方向,另一对面垂直于圆周切线方向。作用在前者上的正应力,就是径向应力σr,它紧贴围岩与支护的接触面,直接决定作用在衬砌或锚喷结构上的围岩压力;作用在后者上的正应力,就是切向应力σθ,也叫环向应力,它决定了洞壁围岩是否会发生压剪破坏或者片帮。
如果用直角坐标的σx、σy去描述这个状态,也不是不可以,但物理意义会被绕弯子。比如你看到洞壁某一点σx是–3MPa、σy是–12MPa,单看这两个数字很难直接判断这个点是否危险。可如果把坐标系旋转到“径向+切向”,得到σθ=–25MPa、σr≈0MPa,就能立刻意识到洞壁无径向约束、环向应力高度集中,这恰恰是围岩破坏的先决条件。
在岩体力学里有一个非常经典的对照:圆形孔洞周围的应力集中系数在弹性条件下理论解很清晰,洞壁切向应力可以达到原岩应力的2倍甚至更高,而径向应力在洞壁处必须等于零或等于支护反力。这类直观认识全部建立在极坐标变量的基础上。
1.2 FLAC 3D的输出坐标和工程坐标之间有偏差
FLAC 3D是一套基于有限差分方法的连续介质力学程序,zone(单元)保存应力张量,gridpoint(节点)保存位移、速度。软件默认情况下,所有应力和位移分量都按全局笛卡尔坐标系输出。zone.stress.xx是x方向的正应力,zone.stress.yy是y方向正应力,zone.stress.zz是z方向正应力,zone.stress.xy是xy平面内的剪应力。节点位移也是ux、uy、uz三件套。
这就有意思了:你的巷道明明是圆形的,建模时网格绕着圆心一圈一圈地排布,但计算完成后程序并不会告诉你“这个zone的径向应力是多少”。你得自己去判断每个zone或每个节点位于洞周什么方位角、离圆心多远,然后把直角坐标下的结果投影到当地的径向和切向方向上去。
很多初学者会犯一个错误,以为FLAC 3D里既然能画出环状的应力云图,程序内部就已经算好极坐标分量的。实际上那个云图仍然是sxx或syy在空间上的分布,只是网格造型是弧形的,颜色分布看起来像是沿着半径变化。你如果提取一个弧形路径上的sxx数值,会发现它同时混入了角度和半径的影响,不经过坐标旋转,很难得到与经典理论可比的σr或σθ。
1.3 哪些情况适合用极坐标处理结果
不是说所有FLAC 3D模型都需要做极坐标转换,我建议你先判断自己的问题是否属于下面这几类:
- 圆形或近似圆形的水平巷道、隧道、盾构管片模型;
- 竖井、钻孔、桩孔周围的应力场,井轴和模型轴重合;
- 具有曲线边界的岩土结构(比如弧形挡土墙、拱坝坝肩、曲线形堤坝),关心面外法向和切向的受力;
- 需要与Kirsch理论解、芬纳公式、卡斯特纳公式等解析解做对比验证;
- 沿洞周布置了多个监测点,要比较不同角度的变形规律。
如果模型是矩形洞室、边坡这类问题,直接用直角坐标输出通常就够了,硬要做极坐标反而有强行套公式的嫌疑。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从FLAC 3D里取数据:三条能落到实处的路径
拿到原始数据是所有后处理的前提,这一节先讲清楚“怎么把FLAC 3D里的笛卡尔应力、位移分量提取出来”。有三类做法我比较常用,分别适用于不同场景。
2.1 选对网格形状:极坐标提取的前提是能定义圆心和半径
在谈数据提取之前,必须看一眼模型网格。如果是一个圆形洞室模型,网格最好画成从圆心向外辐射的“蜻蜓翅膀状”,也就是径向线加同心弧段把平面切分,这样每个zone的几何信息天然包含圆心距和角度信息。FLAC 3D建模时可以用cylindrical隧道开挖命令配合放射状网格生成,也可以用其他前处理软件先画好再导入。
我见过一个同事直接用一个矩形大网格中间挖掉一个圆洞来做隧道模型,洞周网格完全不是辐射状的。在那种模型里做极坐标提取虽然也有可能,但精度和可解释性都会大打折扣。因为一个矩形zone完全可能跨越好几个角度区间,你用它形心的坐标去代表该处的径向应力,误差较大,而且洞壁应力集中区域根本不会被弧形网格很好地捕捉。
建模阶段就要想清楚后处理想要什么:给洞壁留至少8到16个等分角度段,每一段里至少有两三圈zone,这样洞壁附近的应力和位移随角度的变化才能画出一条光滑曲线。
2.2 history测点法:适合少量关键点连续跟踪
如果只想关注洞周的某几个点,比如拱顶、拱底、左右帮,那用history记录最省事。FLAC 3D支持对zone和gridpoint做history记录。
在建模完成后,可以在洞壁关键位置用zone history记录该zone的应力分量,或者用gridpoint history记录节点的位移分量。这个方法的优点是非常轻量,计算完成后直接plot history就能看变化曲线。
但history法有几个限制:
- history记录的是固定的zone或gridpoint,如果你的网格在计算过程中发生大变形,zone的几何位置已经移动了,你记录的应力仍然是“这个单元现在的应力”,不是“这个空间点位置的应力”;
- 每个history只能针对单一单元,想要沿洞周每15度取一个点,就得布置24个history,后期整理数据很啰嗦;
- history给出的是全局坐标系下的sxx、syy,并不会自动给你σr、σθ。
所以history法适合“知道大概要看哪个点”的情况。比如判断洞壁拱顶是否进入塑性、位移是否收敛,用history就够了。
2.3 zone遍历扫描:用FISH把模型里所有单元筛一遍
当你想看完整的应力随半径和角度变化图时,就不要只靠history了。最通用的做法是用FISH对zone做一次遍历,按zone形心的极坐标位置筛选并求平均。
FISH逻辑大致是这样的:
- 确定圆心坐标cx、cy,计算每个zone形心相对圆心的dx、dy;
- 计算每个zone的半径r和方位角θ;
- 判断该zone是否位于目标半径区间和目标角度区间内;
- 命中后把zone.stress.xx、zone.stress.yy、zone.stress.xy读出来;
- 按多个zone求平均,降低单个单元的数据波动。
需要注意的是,FLAC 3D不同版本中FISH访问zone应力的写法不完全一样,老版本常用z_sxx(p_z)这类内建函数,新版本一般推荐使用zone.stress.xx(zone)这类基于对象的访问方式。我建议在实际写之前先查自己版本自带的fish scripting manual,确认关键字。
另外一个非常容易忽略的问题:zone的应力存储在zone中心,而位移存储在节点上。所以你要提取“半径r处的一圈应力”,实际操作中经常取一定半径范围内的所有zone做平均;而要提取“半径r处的一圈位移”,则是对落在该半径附近的节点做插值或平均。两者的空间采样方式不同,不要混为一谈。
2.4 外部文件导出法:交给Python或Excel处理更灵活
当年第一版脚本我用FISH写,后来发现每次微调参数都要重新跑一遍模型文件,效率太低。后来改成用history或者批量输出把结果导成文本文件,再在Python里做极坐标变换和绘图,灵活度高了非常多。
具体做法也很简单:
- 用FISH遍历需要输出的zone或gridpoint;
- 用io.write或list write把坐标和应力/位移分量写成ASCII文件;
- Python中用pandas或numpy读取;
- 然后直接做后续计算。
一张比较典型的数据行大概长这样:
csv复制id,x,y,z,sxx,syy,szz,sxy,r,theta_deg
1024,2.981,0.352,0.0,-3.2e6,-8.7e6,-4.1e6,-1.2e6,3.002,6.73
1025,2.873,0.681,0.0,-3.4e6,-9.1e6,-4.0e6,-1.8e6,2.952,13.34
有了r和theta_deg,后续的所有转换都变得很容易。这个办法我在实际项目里用得最多,尤其是需要把FLAC 3D结果和现场监测数据、解析解放在同一张图上的时候。
下面用一个表格把这三种路径的特点说清楚:
| 提取方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| history测点 | 少量固定位置的过程曲线 | 简单、占用资源少 | 点少、只给全局坐标分量 |
| FISH zone遍历 | 全场应力/位移随角与半径变化 | 数据完整、能做平均 | 脚本调试麻烦、版本API需查 |
| 外部文件导出 | 需要二次加工和对比时 | 灵活、适合后处理 | 额外文件交互、需写转换代码 |
3. 坐标变换:应力张量和位移矢量的旋转到底该怎么写
3.1 从直角坐标到极坐标的应力旋转公式
这一步是整个主题的核心。假设直角坐标系的x轴与极坐标的0°方向重合,θ从x轴正向逆时针旋转到径向方向。已知平面内一点的应力分量为σx、σy、τxy,那么这个点附近的径向正应力、环向正应力和剪应力可以用张量旋转公式得到。
我的推导习惯,是先从应力转轴公式出发。说白了,应力张量是一个二阶张量,坐标旋转时满足:
σ' = R·σ·Rᵀ
在二维平面内,如果旋转角度为θ,那么将应力分量展开后就是下面三个常见表达式:
σr = σx·cos²θ + σy·sin²θ + 2·τxy·sinθ·cosθ
σθ = σx·sin²θ + σy·cos²θ − 2·τxy·sinθ·cosθ
τrθ = (σy − σx)·sinθ·cosθ + τxy·(cos²θ − sin²θ)
这里要注意θ的定义。对同一个zone,如果它的形心相对圆心的方位角是θ,那么该zone的径向方向就是θ方向。这三个公式就是把你模型局部坐标系下的应力分量,改写成“以径向和切向为坐标轴”的分量。
实际上你不用手算这三个三角函数公式的每个系数,因为张量旋转满足线性关系,你只需要把每个应力分量看成一个基元,按上面三个式子组合。
3.2 位移矢量可以用更简单的投影完成
位移是向量,向量的坐标变换比应力张量简单得多。假设某一点的全局位移分量是ux、uy,该点相对圆心的方位角为θ,那么:
径向位移 ur = ux·cosθ + uy·sinθ
切向位移 uθ = −ux·sinθ + uy·cosθ
在隧道工程里,最常用的量是径向位移。如果把位移方向朝向洞内定义为正值,那么对洞壁上的点来说,ux和uy的方向要看模型坐标怎么摆。比如拱顶下沉,在竖直方向上Uy应该是负值(朝向洞内),但在全局坐标里不一定所有径向点都这样。所以工程上更推荐用径向位移绝对值的变化来分析收敛,或者直接用“半径变化量”来定义。
位移有一个比较“坑”的地方:FLAC 3D在初始地应力平衡阶段的位移通常已经通过model solve elastic或者model solve设置了位移归零,所以后续开挖阶段的位移相对值是合理的。如果你的模型没有做初始位移清零,那么极坐标分解出来的位移会叠加上初始地应力场阶段的刚体位移,往往数值异常地大。处理这种问题的一般做法是计算每个阶段之间的位移增量,而不是看绝对位移。
3.3 我整理了一个可以直接用的Python转换函数
因为现在很多人已经开始用FLAC 3D的Python接口,下面这段函数可以直接套用。如果熟悉numpy,坐标变换只是一次向量化运算的事。
python复制import numpy as np
def cartesian_to_polar_stress(sxx, syy, sxy, theta_deg):
"""
将直角坐标系下的应力分量转换到极坐标(径向-环向)坐标系。
Parameters
----------
sxx, syy, sxy : float or np.ndarray
全局坐标下的应力分量,单位保持一致。
theta_deg : float or np.ndarray
该点相对圆心的方位角,单位:度
Returns
-------
sr, st, srt : 径向应力、环向应力、剪应力
"""
theta = np.deg2rad(theta_deg)
c = np.cos(theta)
s = np.sin(theta)
sr = sxx * c**2 + syy * s**2 + 2.0 * sxy * s * c
st = sxx * s**2 + syy * c**2 - 2.0 * sxy * s * c
srt = (syy - sxx) * s * c + sxy * (c**2 - s**2)
return sr, st, srt
def cartesian_to_polar_displacement(ux, uy, theta_deg):
"""
将直角坐标位移矢量分解为径向位移和切向位移。
"""
theta = np.deg2rad(theta_deg)
c = np.cos(theta)
s = np.sin(theta)
ur = ux * c + uy * s
ut = -ux * s + uy * c
return ur, ut
用的时候只需要把从FLAC 3D导出的每一行数据的sxx、syy、sxy和形心相对圆心的方位角喂给函数,返回的sr和st就是该zone的径向与环向应力。
如果你想在程序里直接算θ,不要用atan(dy/dx),因为当dx接近0的时候会出现奇异。更稳妥的写法是:
python复制theta = np.arctan2(dy, dx)
这个细节虽然小,但在洞顶和洞底点(竖直方向)提取数据时特别重要,否则角度会跳到错误象限。
3.4 用弹性理论解做一次验证
坐标变换函数写完之后,最该做的事情是验证。我会先在FLAC 3D里建一个最简单的圆形孔洞平面应力或平面应变模型,让远场应力是静水压力状态,也就是σx=σy=σ0,τxy=0。这种情况下的圆形孔洞解析解非常简单,在半径为r处的应力是:
σr = σ0·(1 − a²/r²)
σθ = σ0·(1 + a²/r²)
其中a是孔半径。在洞壁处r=a,σr=0,σθ=2σ0。这个结果可以用一句话来记忆:洞壁上的切向应力翻倍,径向应力归零。
然后我在模型里沿0度、45度、90度等方向取几个zone,用上面的Python函数做坐标变换,看看计算结果是否分别接近0和2σ0。如果是,那说明从导出到变换这一套流程是通的,后面可以放心用在更复杂的非静水压力场、多层地层模型中。否则就回头检查θ定义、应力分量符号或者导出映射,大多数错误都出在这三处。
下面放一个比较典型的静水压力场验证数据表(这里只是示意数值):
| 角度(°) | 半径r(m) | σx(MPa) | σy(MPa) | τxy(MPa) | 转换σr(MPa) | 理论σr(MPa) | 转换σθ(MPa) | 理论σθ(MPa) |
|---|---|---|---|---|---|---|---|---|
| 0 | 4.0 | 2.35 | 5.65 | 0.00 | 2.35 | 2.50 | 5.65 | 5.50 |
| 30 | 4.0 | 3.18 | 4.82 | 1.44 | 2.43 | 2.50 | 5.57 | 5.50 |
| 60 | 4.0 | 4.82 | 3.18 | -1.44 | 2.57 | 2.50 | 5.43 | 5.50 |
需要注意的是,这组数值只是用来演示趋势,不能当作某个特定模型的精确结果。真实验证时请用你自己的模型数据。
4. 曲线可视化:如何把极坐标数据画得能看、能分析
数据转换完成之后,下一步就是可视化。很多做数值模拟的同行习惯盯着云图看,云图能直观反映应力集中的位置,但很难精确读出某一条线上的变化规律。把数据画成曲线,是极坐标分析中很关键的一步。
4.1 先说最直观的“洞周展开图”
洞周展开图的本质是:把横轴设为角度0°到360°,纵轴设为应力或位移大小。这种图不涉及极坐标绘图的特殊技巧,用matplotlib的普通plot就可以实现。它适合观察应力和位移随角度的变化规律,尤其在非静水压力条件下,洞周各点的应力并不相同。
比如有一个水平应力大、垂直应力小的圆形巷道,洞壁处的环向应力σθ会呈现出两个峰值点和两个谷值点:在垂直方向附近σθ偏高,在水平方向附近σθ反而偏低。当然实际情况取决于侧压力系数。展开图能很清楚地表现出这种“四点状”分布。
画展开图最需要注意横轴的连续性。如果你用np.linspace(0, 360, 100)生成横轴,而测点是按度数分散的,建议先统一换算到0~360度范围,并对角度做排序,再用plt.plot画线。不然点在角度上乱序,连线会像一团乱麻。
我曾经在做“应力变化随开挖面推进”分析时,把不同开挖步的洞周环向应力展开图分别画了6条线放在同一个figure里,可以看到开挖面接近监测断面时环向应力突然增大、远离后趋于稳定的全过程。这种多曲线对比用普通plot远比极坐标图方便。
4.2 真正的极坐标玫瑰图在什么时候用
如果你是给项目汇报做图,或者想把围岩压力沿洞周的分布展示得更直观,那真正的polar plot(极坐标图,也叫玫瑰图)会更有冲击力。所谓玫瑰图,就是角度仍然代表方向,半径方向的长度代表应力数值。洞壁越往外凸,说明那个方向的应力越大。
matplotlib里画极坐标图只需要在创建子图时指定projection='polar':
python复制import numpy as np
import matplotlib.pyplot as plt
theta = np.deg2rad(np.array([0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360]))
stress_r = np.array([0.2, 1.8, 4.2, 7.6, 4.8, 2.1, 0.3, 1.9, 4.5, 8.1, 5.0, 2.2, 0.2])
stress_theta = np.array([11.2, 10.5, 8.4, 6.2, 8.1, 10.1, 11.4, 10.3, 8.0, 5.8, 7.9, 9.8, 11.2])
fig = plt.figure(figsize=(8, 4))
ax1 = fig.add_subplot(121, projection='polar')
ax1.plot(theta, stress_r, label='radial stress')
ax1.fill(theta, stress_r, alpha=0.2)
ax1.set_theta_zero_location('N')
ax1.set_theta_direction(-1)
ax1.legend()
ax2 = fig.add_subplot(122, projection='polar')
ax2.plot(theta, stress_theta, label='tangential stress')
ax2.fill(theta, stress_theta, alpha=0.2)
ax2.set_theta_zero_location('N')
ax2.set_theta_direction(-1)
ax2.legend()
plt.show()
这段代码只是一个画法示范,具体数值请根据你自己的计算结果替换。需要注意matplotlib的极坐标图的0°默认指向右侧,且角度按逆时针方向增加。但洞室问题里我们习惯把0°放在正北(拱顶位置),因此代码里特别加了两行set_theta_zero_location('N')和set_theta_direction(-1),分别把0°放到正北方向、把角度增长方向改为顺时针。如果没有这两个设置,画出来的图和工程现场的方位习惯对不上。
4.3 用QCustomPlot时如何在同一张图上叠加多条曲线
如果你用C++/Qt做自己的前后处理界面,绕不开QCustomPlot这个绘图库。它在2.x版本之后增加了极坐标轴支持,可以用QCPPolarAxisRadial和QCPPolarAxisAngular绘制极坐标图。我经常被一起问到的需求是“画完极坐标后再绘制一条普通plot曲线”,比如说我想把应力玫瑰图和某个理论解曲线叠在一起。
这种场景下我的建议是:不要尝试把“直角坐标曲线”和“极坐标系”硬塞到一个坐标系里。如果你要叠加的是同样以角度为自变量、以应力大小为径向数据的一条线,那它本质上就是一条极坐标曲线,完全可以直接用addGraph加到极坐标轴上,再传入已经转成θ和r的数据点。如果你要叠加的是那种极坐标上很难表达的普通直角坐标曲线(比如某一条水平线段),那就选择在单独的直角坐标轴里画,或者把该曲线按所需的极坐标形式转换后再加进去。
实际操作中,QCustomPlot的极坐标轴和直角坐标轴共存在同一个QCPAxisRect里有一定难度,最推荐的做法还是给QCustomPlot添加两个不同的graph,或者直接使用两个坐标层叠加。坦率地说,如果你只是做一次性数据分析,而不是要做长期使用的桌面工具,我不会优先推荐QCustomPlot,Python的matplotlib能省掉很多底层的坐标轴管理逻辑。
4.4 实测数据太毛刺:不要急着滤波,先查数据本身
我第一次把FLAC 3D导出数据画成极坐标曲线时,发现曲线像锯齿一样,相邻两个zone的应力值跳动非常大。一开始我以为是数值计算不收敛,后来仔细检查才发现,我的遍历脚本在过滤zone时没有做角度边界判断,导致某个0~30度区间里混入了几个位于350~360度的zone。由于atan2返回的角度范围是-180到180度,不统一归一到0~360度,就会出现这种“角度错位”。
把角度统一处理之后,毛刺少了很多。但还剩下一些小锯齿,这种是正常的,因为FLAC 3D采用有限差分网格,相邻zone的形心半径和角度并不完全均匀,尤其是洞壁附近为了捕捉应力梯度往往加密网格,应力值本身就有微小的空间振荡。
如果锯齿还影响了你对整体趋势的判断,可以合理地做一次滑动平均或对等角度区间bin内的zone应力求均值。比如每5度一个bin,把落在该bin内的所有zone应力取平均,再作为该角度位置的应力代表值。这种做法既保留了趋势,又不会让人觉得你在人为“磨平”数据。这里的关键是:滤波要基于几何区间平均,而不是简单地把数据点拿去平滑。
5. 工程实例:弧形堤坝位移监测中的极坐标分解
5.1 堤坝位移监测为什么要做“极坐标”分解
很多朋友看到“堤坝位移监测”这个词,会觉得这不是一个极坐标问题。确实,笔直河流上的均质土坝,用直角坐标就够了:水平位移量沿上下游方向,沉降沿竖直方向。
但如果堤坝是修建在弯曲河道上的,坝轴线呈弧形,那么每个监测点处的“水平位移”到底是沿什么方向?常规监测量测仪器给出的水平位移分量通常是北向和东向的平面坐标增量,这个增量并不能直接告诉你坝体在“垂直坝轴线方向”上有没有被水压力推开、在“顺坝轴线方向”有没有产生拉伸或压缩变形。
想让监测数据具备工程指向性,就必须先定义一个局部坐标系。做法是:找到弧形坝轴线的圆心,把每个监测点相对圆心的方位角算出来,然后把北东方向(即全局直角坐标方向)的水平位移分解成径向位移和切向位移。径向位移就是垂直于坝轴线的法向位移,切向位移就是沿着弧形坝轴线的切向位移。
5.2 测点布置和FLAC 3D中的协同处理
我在实际项目中处理过一个类似的弧形堤坝问题。FLAC 3D模型里建了一段带弧形拐角的堤坝,坝体表面沿弧线布置了若干位移监测点。我要做的是把模拟得到的每个监测点位移,和现场自动化监测的水平位移数据放在同一坐标系下对比。
第一步,先把所有测点的x、y坐标导出来,用圆弧拟合确定圆心坐标。这里要用到deldir或者最小二乘圆拟合,不能只凭肉眼选圆心,否则后面所有分解结果都会系统性偏移。
第二步,对每个测点计算方位角θ,并统一换算到0~360度。如果坝体弧线跨过了0度线,要特别小心,不要让某个点突然跳到359度附近。
第三步,调用位移分解函数,把FLAC 3D和现场测得的ux、uy都分解成ur和ut。然后沿着弧长或方位角把实测值和模拟值画在同一张展开图上。
当时这个项目里有一个很有意思的结论:在一个弧段半径约240米、弧长接近100米的坝段里,切向位移分量不可忽略。在弧形段的中部某测点,切向位移占水平位移的将近35%。如果你只对比水平合位移或者只看x、y分量,很可能会低估坝体在某个局部方向的变形趋势。这也从侧面说明,在弧形结构中,一个合适的局部坐标分解不是锦上添花,而是必要操作。
当然要提醒一句:现场的自动监测仪器测得的是地球坐标系下的位移,FLAC 3D没有直接的“极坐标监测”指令,两者都需要在导出后做后处理,千万不要等到模型跑完再去翻全局坐标下的位移云图来猜法向变形。
5.3 分析位移分量时我最看重的几个判定
做完极坐标分解之后,怎么利用这些结果去评价坝体状态,我自己总结了几个经验性的判定逻辑:
- 径向位移持续增大且速率不衰减,说明水压力主导的推挤效应在加强,要警惕坝基或坝体中部的变形是否已经进入塑性阶段;
- 切向位移在弧段两侧出现反向,说明弧形坝段存在明显的“拱效应”,这种情况下监测点两端的差异变形比单点绝对位移更有预警价值;
- 纯极坐标转换后的径向位移,非常容易被全局坐标系下的初始位移偏移干扰。因此所有对比都要用位移增量,而不是用累计的绝对位移值。
在FLAC 3D中,通过history记录坝面节点位移时,通常需要把初始地应力平衡阶段的位移清零,在开挖或填筑阶段记录增量位移。否则你最后做出来的极坐标位移云图上会叠加上一个很大的初始“假位移”,把所有趋势都掩盖掉。
6. FLAC 3D应力参数敏感性以及我总结的避坑清单
6.1 应力和哪些参数相关:不要只盯着本构模型
有博主问我:“FLAC 3D里面的应力到底和什么参数有关?”这个问题表面上看起来简单,但实际上包含两层意思。
第一层是材料参数对应力分布的影响。在线弹性范围内,洞室周围的应力大小几乎和弹性模量E无关,主要受泊松比ν和初始应力场影响。这一点经常有人搞反,觉得模量越大应力越大,其实那指的是应变和位移;弹性模量增大,位移减小,但洞壁切向应力集中系数几乎不变。当模型进入塑性状态后,黏聚力c、内摩擦角φ、剪胀角以及抗拉强度会决定应力重分布的极限状态,也就是塑性区的范围以及洞壁最终能够承受的切向应力上限。
第二层是单元应力输出本身会受到求解过程和网格的影响。比如开挖步数、是否做初始地应力平衡、zone尺寸是否合理,都会影响同一位置的应力读数。这也是为什么做极坐标提取时,我更倾向于沿角度区间取多个zone的平均值,而不是直接用单单元的原始值来下结论。
6.2 我踩过的五个很典型的坑
第一个坑是符号约定搞反。FLAC 3D默认的应力约定在标准版本里一般遵循拉为正压为负,但岩土工程习惯是压为正,很多人做转换前不做符号归一化就套公式,结果径向应力和切向应力的正负全反了,画出来的云图颜色完全对不上。我的经验是先做一个静水压力单轴压缩验证,确认当前版本里sxx是负值还是正值。
第二个坑是把zone应力点位置当成了zone的几何中心。FLAC 3D允许zone不是完全规则的六面体,它的应力存储点不一定在几何中心。虽然大多数情况下误差不大,但如果你的网格在某处有严重偏斜,提取时应尽量使用程序内置的zone.pos函数获取应力点坐标,而不是自己拿节点坐标取平均。
第三个坑是符号θ的方向没统一。后续画图用到了不同角度的数据,但一部分来自atan2(y, x),一部分来自理论公式推导,导致相位差90度或者方向反了。最终图纸要和现场方位一致时才发现,所有应力沿洞周转了一圈。这类问题只能靠多头对图,把0度点、90度点单独提出来人工核对。
第四个坑是变形大时仍然按初始半径去定义θ. 如果模型经历了大变形或者网格畸变严重,应该使用更新后的节点坐标来计算位置和角度,否则做出来的极坐标曲线对应的空间位置已经和实际单元位置偏差很大了。
第五个坑是导出纯坐标和应力数据却丢掉了time step信息。FLAC 3D里每个zone应力都是在多个计算步后保存的,如果你导出时没有记录step或者阶段标识,后处理时想绘制“应力-开挖步”曲线就会无从下手。建议每次导出都加上step参数列。
6.3 极坐标提取流程检查清单
下面这个清单是我目前每次做这一类后处理时都会过一遍的流程,供大家直接抄:
- 确认建模阶段已经把圆心位置、半径范围记下来;
- 确认本版本中zone应力分量的符号约定,用解析解验证;
- 导出数据时包含x、y、z、sxx、syy、szz、sxy、节点位移等必要分量;
- 每个zone或节点利用atan2准确计算θ,并统一到0~360度;
- 将应力按张量旋转公式变换为σr、σθ、τrθ,将位移按向量分解为ur、uθ;
- 沿角度和半径区间做统计平均,去掉非期望范围的数据点;
- 先用静水压力圆形洞室解析解验证流程正确性;
- 绘图时先画展开图做趋势分析,再画玫瑰图做展示;
- 核对0度点、90度点、洞壁点等关键位置的数值是否与工程经验相符。
按照这个清单走一遍,基本上不会出现大的方向性错误。如果有异常,回到第一步查,问题通常出在你以为没问题的地方。
对FLAC 3D来说,极坐标不是一个内置的模型坐标系,而是一个描述“圆形结构周围的力学响应”所需要的后处理工具。它的核心运算不过是一次坐标旋转,但它能把你从一堆云图里解放出来,让你直接看到洞室围岩沿半径方向和环向的受力与变形。希望这篇文章能帮你把这条路走通。
