Plaxis代理封装框架——完整的基坑仿真解析(二)

本文接上:Plaxis代理封装框架——完整的基坑仿真解析(一)

写在前面

为了更好地介绍这个代理框架,以降低使用同学的操作门槛。

由于这个框架是原来笔者的科研过程中流式代码转换过来的,且在完整的框架开发时由于对Plaxis机理和机制理解有限,因此难免存在疏漏和错误,还请各位同学及时提出,辅助修正。当前笔者的相关工作也已经从之前的流式代码切换到当前框架,优化的频率较高,因此代码库更新的速度较快,同学们使用这个框架时,应当首先运行以下命令检查当前的代码库是否有更新,然后再运行业务代码。

1
2
3
4
5
# 检查并安装最新的代码库
pip install plaxisproxy_excavation -U

# 其他可选安装的模块:pandas(数据分析)、openpyxl(Excel读写处理提速)、scipy(KD树实现空间最近邻算法,提升结果提取的效率)
pip install pandas openpyxl scipy

testmapper.py结构解析

什么是testmapper.py

testmapper.py基于开挖工程对象,完整的定义了一个基坑工程一键建模、网格划分,施工阶段划分和计算结果提取完整阶段。首先创建了一个函数来实例化一个基坑工程对象,而后通过调用Builder对象在Plaxis软件中完成建模。Builder中内置了数据提取接口,使其能够从计算结果中提取任意的数据。因此本例演示了提取所有基坑围护墙三个方向变形,并将结果使用pandasopenpyxl写入Excel表格中的完整代码。

我将通过在原始代码中补充更加详细的注释,以详细地分析当前部分的关键算法和实现细节:

以下涉及详细的代码解析,为了精简篇幅部分代码会有些许省略,可以下载对照源码阅读解析。

第一部分详细分析:导入和基础设置

1.1 库导入架构解析

这个脚本构建了一个完整的 PLAXIS 3D 基坑分析系统,采用模块化架构:

核心运行层:

  • PlaxisRunner - PLAXIS 计算引擎连接器,负责与 PLAXIS 服务器通信
  • ExcavationBuilder - 基坑模型构建器,将抽象模型转换为 PLAXIS 具体对象
  • FoundationPit - 基坑数据容器,存储所有几何、材料和结构信息
  • PlaxisOutput - Plaxis 结果查询引擎连接器,负责打开结果查看面板以及提取计算结果

数据模型层:

  • ProjectInformation - 项目元数据(单位制、模型范围等)
  • Phase - 施工阶段管理,支持继承关系
  • BoreholeSet - 钻孔数据集合,包含分层土体信息

材料系统:

  • SoilMaterialFactory - 土体材料工厂,使用 SoilMaterialsType.MC 创建摩尔-库仑材料
  • ElasticPlate - 弹性板材料(用于地下连续墙)
  • ElasticBeam - 弹性梁材料(用于水平支撑)

几何系统:

  • Point, PointSet, Line3D, Polygon3D - 三维几何基元
  • 采用面向对象几何表示,便于后续的网格生成和结果提取

1.2 几何辅助函数详细说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def rect_wall_x(x: float, y0: float, y1: float, z_top: float, z_bot: float) -> Polygon3D:
"""创建X方向的矩形墙多边形

关键算法:在固定X坐标的垂直平面上创建矩形多边形
生成顺序:顶部→底部,形成闭合多边形环

参数:
x: 墙的固定X坐标
y0, y1: Y方向范围(墙的宽度方向)
z_top, z_bot: Z方向范围(墙的深度方向)

返回:
由5个点组成的多边形(首尾重复形成闭合)
"""
pts = [
Point(x, y0, z_top), # 左上角
Point(x, y1, z_top), # 右上角
Point(x, y1, z_bot), # 右下角
Point(x, y0, z_bot), # 左下角
Point(x, y0, z_top), # 回到起点形成闭合
]
return Polygon3D.from_points(PointSet(pts))

几何生成原理:

  • 地下连续墙被建模为垂直的平面多边形
  • 每个墙由4个角点+1个重复起点构成5点多边形
  • 这种表示方法便于 PLAXIS 进行板单元网格划分
  • Z方向表示墙的埋深,从地表(z_top)到墙底(z_bot)
1
2
3
4
5
6
7
8
def line_2pts(p0: Tuple[float, float, float], p1: Tuple[float, float, float]) -> Line3D:
"""两点创建直线 - 用于支撑梁和降水井

支撑梁算法:两点确定一条直线段
降水井算法:井筒被简化为垂直线段,从地表到滤管底部
"""
a = Point(*p0); b = Point(*p1)
return Line3D(PointSet([a, b]))

第二部分详细分析:降水井布局算法

这里根据一定的规则设计了一套自动生成降水井的代码,不感兴趣或阅读吃力的同学可直接跳过,不影响直接通过流水线生成降水井。

2.1 几何计算核心算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def _poly_area_sign(xy):
"""计算多边形面积符号 - 判断多边形顶点顺序

使用鞋带公式计算有向面积:
A = 1/2 * Σ(x_i*y_{i+1} - x_{i+1}*y_i)

关键点:
- 正值:顶点逆时针顺序(CCW)
- 负值:顶点顺时针顺序(CW)
- 零值:退化多边形

这个符号用于确定边界井的外法线方向
"""
a = 0.0
for (x1,y1),(x2,y2) in zip(xy, xy[1:]+xy[:1]):
a += (x1*y2 - x2*y1)
return 1 if a > 0 else -1 if a < 0 else 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def _point_in_polygon(pt, poly):
"""射线法点包含检测 - 经典几何算法(防止降水井和墙等产生交叉)

算法原理:从点向右发射水平射线,统计与多边形边界相交次数
- 奇数次:点在多边形内
- 偶数次:点在多边形外

特殊处理:
- 水平边界的精确处理
- 避免除零错误(+1e-12)
- 顶点在射线上的特殊情况
"""
x, y = pt
inside = False
n = len(poly)
for i in range(n):
x1,y1 = poly[i]; x2,y2 = poly[(i+1)%n]
# 检查射线与边的交点
if ((y1>y) != (y2>y)) and (x < (x2-x1)*(y-y1)/(y2-y1+1e-12) + x1):
inside = not inside
return inside
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def _dist_point_to_segment(px, py, x1, y1, x2, y2):
"""点到线段距离计算 - 向量投影方法(用于分析降水井的某个点到现有结构的距离)

算法步骤:
1. 计算线段向量 v 和点到起点向量 w
2. 计算投影参数 c1 = v·w(点积)
3. 如果 c1 ≤ 0,最近点是线段起点
4. 如果 c2 ≤ c1,最近点是线段终点
5. 否则,计算投影点并求距离

这个函数用于确保内部井与边界保持安全距离
"""
vx, vy = x2-x1, y2-y1 # 线段向量
wx, wy = px-x1, py-y1 # 点到起点向量

c1 = vx*wx + vy*wy # 向量点积,计算投影
if c1 <= 0:
return ((px-x1)**2 + (py-y1)**2)**0.5 # 最近点是起点

c2 = vx*vx + vy*vy # 线段长度的平方
if c2 <= c1:
return ((px-x2)**2 + (py-y2)**2)**0.5 # 最近点是终点

# 计算投影点
b = c1 / (c2 + 1e-12) # 避免除零
bx, by = x1 + b*vx, y1 + b*vy
return ((px-bx)**2 + (py-by)**2)**0.5

2.2 降水井布置策略详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def wells_on_polygon_edges(prefix, poly_xy, z_top, z_bot, q_well, spacing, clearance):
"""边界降水井布置算法(沿着基坑内部并与基坑围护墙保持一定距离,沿着边布井)

工程原理:在基坑周边布置降水井,形成降水帷幕
关键参数:
- spacing: 井间距(通常6-12米)
- clearance: 距边界距离(避免与支护结构冲突)

算法步骤:
1. 遍历多边形的每条边
2. 根据边长和间距计算分段数
3. 计算每段的中心位置
4. 沿法线方向偏移 clearance 距离
5. 创建垂直线段表示井筒
"""
wells = []
sign = _poly_area_sign(poly_xy) # 确定多边形方向

for i in range(len(poly_xy)):
x1,y1 = poly_xy[i]
x2,y2 = poly_xy[(i+1)%len(poly_xy)]

# 边向量和长度
ex, ey = x2-x1, y2-y1
elen = max((ex**2+ey**2)**0.5, 1e-9)

# 计算外法线(顺时针多边形)或内法线(逆时针多边形)
nx, ny = ey/elen, -ex/elen # 原始外法线
if sign > 0: # 逆时针多边形需要反转法线
nx, ny = -nx, -ny

# 计算分段数(至少1段)
nseg = max(1, int(elen/spacing))

# 在每个分段点布置井
for k in range(nseg+1):
t = k/float(nseg) # 参数化位置 [0,1]
# 计算井位:边上位置 + 法线方向偏移
px = x1 + t*ex + nx*clearance
py = y1 + t*ey + ny*clearance

wells.append(Well(
name=f"{prefix}_E_{len(wells)+1}", # E表示边界井
line=line_2pts((px, py, z_top), (px, py, z_bot)),
well_type=WellType.Extraction, # 抽水井
q_well=q_well, # 单井抽水量
h_min=z_bot, # 最低水位控制标高
))
return wells
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def wells_grid_in_polygon(prefix, poly_xy, z_top, z_bot, q_well, dx, dy, margin):
"""内部网格井布置算法(在基坑内部等间距、网格式布井)

工程原理:在基坑内部补充布置降水井,增强降水效果
关键参数:
- dx, dy: 网格间距
- margin: 距边界最小距离(避免边界效应)

算法步骤:
1. 计算多边形包围盒
2. 生成规则网格点
3. 筛选在多边形内部且距边界足够远的点
4. 在合格位置布置井
"""
xs = [p[0] for p in poly_xy]; ys = [p[1] for p in poly_xy]
xi, xf = min(xs), max(xs); yi, yf = min(ys), max(ys)
wells = []

# 计算网格划分数量
nx = max(1, int((xf-xi)/dx))
ny = max(1, int((yf-yi)/dy))

# 遍历所有网格点
for ix in range(nx+1):
x = xi + (xf - xi) * ix / max(1, nx)
for iy in range(ny+1):
y = yi + (yf - yi) * iy / max(1, ny)

# 双重筛选条件
if not _point_in_polygon((x,y), poly_xy):
continue # 必须在多边形内
if _min_dist_to_edges((x,y), poly_xy) < margin:
continue # 必须距边界足够远

wells.append(Well(
name=f"{prefix}_G_{len(wells)+1}", # G表示网格井
line=line_2pts((x, y, z_top), (x, y, z_bot)),
well_type=WellType.Extraction,
q_well=q_well,
h_min=z_bot,
))
return wells

2.3 智能井数控制算法深度解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def layout_wells_with_limit(prefix, poly_xy, z_top, z_bot, q_well, 
edge_spacing, grid_dx, grid_dy, clearance,
margin, max_wells=50, dedupe_tol=1e-6):
"""智能井数控制算法 - 核心优化逻辑

工程需求:实际工程中降水井数量受成本和施工限制(通过设置最大井数来控制)
算法目标:在限定井数内获得最优降水效果

策略优先级:
1. 边界井优先(形成降水帷幕)
2. 内部网格井补充(增强降水效果)
3. 自适应间距调整
4. 抽样降级策略
5. 几何去重保证
"""

# 第一阶段:生成边界井
spacing_used = max(0.5, float(edge_spacing)) # 最小间距0.5m
edge_wells = wells_on_polygon_edges(prefix, poly_xy, z_top, z_bot,
q_well, spacing_used, clearance)

# 自适应间距调整算法
safety = 0
while len(edge_wells) > max_wells and safety < 8:
# 计算调整因子:当前井数/目标井数的向上取整
factor = ceil(len(edge_wells) / max_wells)
# 指数级增大间距(至少2倍)
spacing_used *= max(2, factor)
# 重新生成边界井
edge_wells = wells_on_polygon_edges(prefix, poly_xy, z_top, z_bot,
q_well, spacing_used, clearance)
safety += 1 # 防止无限循环

# 抽样降级策略:如果仍超限,均匀抽样
if len(edge_wells) > max_wells:
step = ceil(len(edge_wells) / max_wells) # 计算抽样步长
edge_wells = [edge_wells[i] for i in range(0, len(edge_wells), step)][:max_wells]

# 第二阶段:分配剩余名额给内部网格井
remaining = max(0, max_wells - len(edge_wells))
grid_selected = []
if remaining > 0:
grid_all = wells_grid_in_polygon(prefix, poly_xy, z_top, z_bot,
q_well, grid_dx, grid_dy, margin)
if len(grid_all) > remaining:
# 内部井也进行抽样
step = ceil(len(grid_all) / remaining)
grid_selected = [grid_all[i] for i in range(0, len(grid_all), step)][:remaining]
else:
grid_selected = grid_all

# 第三阶段:几何去重处理
all_wells = edge_wells + grid_selected
wells_unique, wells_dupes, _ = dedupe_wells_by_line(all_wells,
tol=dedupe_tol,
keep="first")

# 最终数量保证
if len(wells_unique) > max_wells:
wells_unique = wells_unique[:max_wells]

# 返回详细统计信息
stats = {
"edge_spacing_used": spacing_used, # 实际使用的边界井间距
"edge_count": len(edge_wells), # 边界井数量
"grid_count": len(grid_selected), # 内部井数量
"unique": len(wells_unique), # 去重后总数
"dupes": len(wells_dupes), # 重复井数量
}
return wells_unique, stats

算法关键点:

  1. 多级降级策略:间距调整 → 抽样 → 去重,逐步满足井数限制
  2. 工程优先级:边界井优先于内部井,符合降水工程实践
  3. 自适应参数:根据多边形尺寸自动计算合适的网格划分
  4. 容错机制:防止无限循环,处理退化情况
  5. 完整统计:提供详细的布置过程统计,便于调试优化

第三部分:几何去重算法和土体材料系统

3.1 几何去重算法深度解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def _as_xyz(p: Any) -> Tuple[float, float, float]:
"""统一坐标提取函数 - 处理多种几何对象类型

算法原理:通过反射机制适配不同的几何类接口
支持的对象类型:
- 具有 x,y,z 属性的对象
- 三元组或列表
- 其他可迭代的坐标表示
"""
if hasattr(p, "x") and hasattr(p, "y") and hasattr(p, "z"):
return float(p.x), float(p.y), float(p.z)
return float(p[0]), float(p[1]), float(p[2])

def _extract_line_endpoints(line: Any) -> Tuple[Tuple[float,float,float], Tuple[float,float,float]]:
"""线段端点提取算法 - 多接口适配

关键算法:通过多种方式尝试获取线段起点和终点
适配策略优先级:
1. line.points 属性(PointSet 或列表)
2. line.point_set 或 line._point_set 的内部 points
3. line.start 和 line.end 属性
4. 直接迭代 line 对象

这种多路径适配确保了与不同几何库的兼容性
"""
pts = getattr(line, "points", None)
if pts and len(pts) >= 2:
return _as_xyz(pts[0]), _as_xyz(pts[1])

# 尝试访问点集对象的内部点
ps = getattr(line, "point_set", None) or getattr(line, "_point_set", None)
inner = getattr(ps, "points", None) or getattr(ps, "_points", None) if ps else None
if inner and len(inner) >= 2:
return _as_xyz(inner[0]), _as_xyz(inner[1])

# 尝试直接起点终点属性
start, end = getattr(line, "start", None), getattr(line, "end", None)
if start is not None and end is not None:
return _as_xyz(start), _as_xyz(end)

# 最后尝试迭代
it = list(iter(line))
if len(it) >= 2:
return _as_xyz(it[0]), _as_xyz(it[1])

raise AttributeError("Cannot extract endpoints from the given line object.")

def _q(v: float, tol: float) -> int:
"""坐标量化函数 - 基于容差的离散化

算法原理:将连续坐标映射到离散的网格索引
q(v, tol) = round(v / tol)

这样在容差范围内的点会被映射到同一个整数索引
例如:tol=1e-6时,1.0000001 和 1.0000002 都会映射到 1000000
"""
return int(round(v / tol))

def _line_key(line: Any, tol: float) -> Tuple[Tuple[int,int,int], Tuple[int,int,int]]:
"""线段规范化键值生成算法

关键算法:
1. 提取线段端点
2. 对坐标进行量化离散化
3. 规范化端点顺序(确保起点≤终点)

这样几何上相等的线段(无论方向)会有相同的键值
"""
(x0, y0, z0), (x1, y1, z1) = _extract_line_endpoints(line)
a = (_q(x0, tol), _q(y0, tol), _q(z0, tol))
b = (_q(x1, tol), _q(y1, tol), _q(z1, tol))
return (a, b) if a <= b else (b, a) # 规范化顺序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def dedupe_wells_by_line(wells: Iterable[Any], tol: float = 1e-6, 
keep: str = "first") -> Tuple[List[Any], List[Any], Dict]:
"""降水井去重主算法 - 基于几何位置去重

工程需求:避免在同一位置重复布置降水井
算法复杂度:O(n) 使用哈希表进行重复检测

参数:
- tol: 几何容差(1e-6 ≈ 0.001mm,工程精度足够)
- keep: 保留策略 "first"|"last"

返回:
- unique: 去重后的唯一井列表
- dupes: 被去除的重复井列表
- key_to_master: 键值到主对象的映射
"""
key_to_master: Dict[Tuple[Tuple[int,int,int], Tuple[int,int,int]], Any] = {}
unique: List[Any] = []
dupes: List[Any] = []

if keep not in ("first", "last"):
raise ValueError("keep must be 'first' or 'last'")

for w in wells:
line = getattr(w, "line", w) # 获取井的几何线段
k = _line_key(line, tol) # 计算规范化键值

if k in key_to_master:
# 发现重复井
if keep == "last":
# "last"策略:用新井替换旧井
prev = key_to_master[k]
if prev in unique:
unique.remove(prev)
dupes.append(prev)
key_to_master[k] = w
unique.append(w)
else:
# "first"策略:保留第一个,丢弃后续
dupes.append(w)
else:
# 新井,添加到唯一列表
key_to_master[k] = w
unique.append(w)

return unique, dupes, key_to_master

3.2 土体材料系统详细分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def mk_soil_overrides(names: Iterable[str], active: Optional[bool] = None, 
deformable: Optional[bool] = None) -> Dict[str, Dict[str, bool]]:
"""土体状态覆盖配置生成器

工程原理:在施工阶段中控制土体的激活/冻结状态
- active: 土体是否参与计算(冻结的土体不产生应力)
- deformable: 土体是否可变形(刚性土体位移为零)

应用场景:
- 开挖阶段:开挖区土体设为 inactive
- 支撑阶段:保留区土体可能设为 undeformable
"""
overrides: Dict[str, Dict[str, bool]] = {}
for nm in names:
opts: Dict[str, bool] = {}
if active is not None:
opts["active"] = bool(active)
if deformable is not None:
opts["deformable"] = bool(deformable)
if opts:
overrides[nm] = opts
return overrides

第四部分:基坑组装核心算法

4.1 项目信息配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def assemble_pit(runner: Optional[PlaxisRunner] = None) -> FoundationPit:
"""基坑模型组装主函数 - 完整的工程模型构建

工程规模:20×16米矩形基坑,开挖深度9米
支护体系:地下连续墙+三道水平支撑+降水井
施工阶段:4个主要施工阶段
"""

# 1) 项目信息配置 - 工程基准设置
proj = ProjectInformation(
title="Rectangular Pit – DWall + Braces + Wells",
company="Demo",
dir=".",
file_name="demo_excavation.p3d", # PLAXIS 3D 文件格式
comment="Builder/PhaseMapper demo",
model="3D", # 三维模型
element="10-noded", # 10节点高阶单元(精度更高)
length_unit=Units.Length.M, # 米制单位
force_unit=Units.Force.KN, # 千牛
stress_unit=Units.Stress.KPA, # 千帕
time_unit=Units.Time.DAY, # 天(施工进度)
gamma_water=9.81, # 水重度 9.81 kN/m³
x_min=-345, x_max=345, # 模型X范围:690米(足够大的边界)
y_min=-50, y_max=50, # 模型Y范围:100米
)

pit = FoundationPit(project_information=proj)

模型范围设计原理:

  • X方向690米:确保边界效应不影响基坑区域
  • Y方向100米:提供足够的侧向约束距离
  • 10节点单元:比6节点单元精度更高,适合复杂应力分析

4.2 智能土体分层发现算法

1
2
3
4
5
6
7
8
9
10
11
12
# 智能发现开挖土体和保留土体
excav_names: List[str] = []
remain_names: List[str] = []
if runner is not None:
try:
# 通过Runner自动识别土体分区
excav_names = runner.get_excavation_soil_names(prefer_volume=True)
remain_names = runner.get_remaining_soil_names(prefer_volume=True)
print(f"[MAPPER] excav soils: {excav_names}")
print(f"[MAPPER] remain soils: {remain_names}")
except Exception as ex:
print(f"[MAPPER] soil split discovery failed: {ex}")

土体分区自动化:

  • prefer_volume=True:优先基于体积计算进行土体分类
  • 开挖区土体:在基坑范围内的土体
  • 保留区土体:在基坑范围外的土体
  • 这种自动化减少了手动配置错误

4.3 土体材料库构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 2) 土体材料库 - 8种典型地层材料
fill = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Fill", # 摩尔-库仑本构
E_ref=15e6, c_ref=5e3, phi=25.0, psi=0.0, # E=15MPa, c=5kPa, φ=25°
nu=0.30, gamma=18.0, gamma_sat=20.0, # ν=0.3, γ=18kN/m³
e_init=0.60 # 初始孔隙比 0.6
)

# 软粘土层 - 典型滨海软土特性
soft_clay = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Soft_Clay",
E_ref=10e6, # 弹性模量 10MPa(软土较低)
c_ref=18e3, # 粘聚力 18kPa(粘土特性)
phi=20.0, # 内摩擦角 20°(粘土摩擦角较小)
psi=0.0, # 剪胀角 0°(粘土不剪胀)
nu=0.35, # 泊松比 0.35(粘土较高)
gamma=17.5, # 天然重度 17.5kN/m³
gamma_sat=19.0, # 饱和重度 19.0kN/m³
e_init=0.95 # 高孔隙比(软土特征)
)

# 粉质粘土 - 过渡地层
silty_clay = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Silty_Clay",
E_ref=18e6, c_ref=12e3, phi=23.0, psi=0.0,
nu=0.33, gamma=18.0, gamma_sat=19.5, e_init=0.85
)

# 细砂层 - 透水层,降水主要目标
fine_sand = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Fine_Sand",
E_ref=35e6, c_ref=1e3, phi=32.0, psi=2.0, # c=1kPa(砂土粘聚力很小)
nu=0.30, gamma=19.0, gamma_sat=21.0, e_init=0.55
)

# 中砂层 - 更好工程特性
medium_sand = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Medium_Sand",
E_ref=60e6, c_ref=1e3, phi=35.0, psi=3.0,
nu=0.28, gamma=19.5, gamma_sat=21.5, e_init=0.50
)

# 砾砂层 - 高承载力地层
gravelly_sand = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Gravelly_Sand",
E_ref=90e6, c_ref=1e3, phi=38.0, psi=5.0, # φ=38°(砾砂摩擦角大)
nu=0.26, gamma=20.0, gamma_sat=22.0, e_init=0.45
)

# 全风化岩 - 岩土过渡带
cdg = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Completely_Decomposed_Rock",
E_ref=120e6, c_ref=25e3, phi=36.0, psi=4.0, # c=25kPa(岩土粘聚力)
nu=0.26, gamma=20.5, gamma_sat=22.5, e_init=0.40
)

# 中等风化岩 - 基岩层
mwr = SoilMaterialFactory.create(
SoilMaterialsType.MC, name="Moderately_Weathered_Rock",
E_ref=250e6, c_ref=40e3, phi=40.0, psi=6.0, # E=250MPa(岩石刚度)
nu=0.25, gamma=21.0, gamma_sat=22.8, e_init=0.35
)

for m in (fill, soft_clay, silty_clay, fine_sand, medium_sand, gravelly_sand, cdg, mwr):
pit.add_material("soil_materials", m)

土体参数设计原理:

  • 刚度梯度:从填土15MPa到岩石250MPa,符合地层变化规律
  • 强度参数:粘聚力从5kPa到40kPa,内摩擦角从20°到40°
  • 重度变化:从18kN/m³到21kN/m³,反映地层压实程度
  • 孔隙比:从0.95到0.35,体现土体密实度变化

4.4 钻孔系统构建算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3) 钻孔系统 - 12个控制性钻孔
GW_HEAD_NEAR_SURF = -3.5 # 地下水位埋深3.5米

# 钻孔BH1的详细分层(其他钻孔类似)
bh1_layers = [
BoreholeLayer("Fill@BH1", 0.0, -3.0, sl_fill),
BoreholeLayer("Soft_Clay@BH1", -3.0, -10.0, sl_soft_clay),
BoreholeLayer("Silty_Clay@BH1", -10.0, -15.0, sl_silty_clay),
BoreholeLayer("Fine_Sand@BH1", -15.0, -21.0, sl_fine_sand),
BoreholeLayer("Medium_Sand@BH1", -21.0, -29.0, sl_medium_sand),
BoreholeLayer("Gravelly_Sand@BH1", -29.0, -35.0, sl_gravelly_sand),
BoreholeLayer("Completely_Decomposed_Rock@BH1",-35.0, -42.0, sl_cdg),
BoreholeLayer("Moderately_Weathered_Rock@BH1", -42.0, -50.0, sl_mwr),
]

钻孔布置策略:

  • 控制点分布:12个钻孔在基坑周边和内部形成控制网络
  • 分层变化:不同钻孔的层厚略有变化,模拟真实地层波动
  • 水位统一:所有钻孔共享同一水位面(-3.5米)

4.5 支护结构材料系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 5) 结构材料
dwall_mat = ElasticPlate(name="DWall_E",
E=30e6, # 弹性模量 30GPa(C30混凝土)
nu=0.2, # 泊松比 0.2
d=0.8, # 墙厚 0.8米
gamma=25.0) # 混凝土重度 25kN/m³

brace_mat = ElasticBeam(name="Brace_E",
E=35e6, # 弹性模量 35GPa(钢材)
nu=0.2,
gamma=25.0) # 考虑防腐涂层等的综合重度

pit.add_material("plate_materials", dwall_mat) # 板材料(地下连续墙)
pit.add_material("beam_materials", brace_mat) # 梁材料(水平支撑)

结构材料设计:

  • 地下连续墙:C30混凝土,0.8米厚,提供主要挡土功能
  • 水平支撑:钢材,提供水平约束,控制墙体位移

第五部分:支护结构布置算法

5.1 地下连续墙布置系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 6) 地下连续墙系统 - 复杂多边形基坑支护
wall_specs = [
("wall_start", "x", -115.0, -14, 14), # 起始墙段

# 底部墙段序列(逆时针布置)
("wall_b_1", "y", -14, -115, -99), # 南侧西段
("wall_b_2", "x", -99, -14, -12), # 西侧南段
("wall_b_3", "y", -12, -99, -39), # 内部过渡段
("wall_b_4", "x", -39, -12, -16.5), # 西侧中段
("wall_b_5", "y", -16.5, -39, -13), # 内部连接段
("wall_b_6", "x", -13, -16.5, -13), # 短连接段
("wall_b_7", "y", -13, -13, 98), # 内部纵向段
("wall_b_8", "x", 98, -13, -14.5), # 东侧南段
("wall_b_9", "y", -14.5, 98, 115), # 南侧东段
("wall_end", "x", 115, -14.5, 14.5), # 结束墙段

# 顶部墙段序列(对称布置)
("wall_t_1", "y", 14, -115, -99), # 北侧西段
("wall_t_2", "x", -99, 12, 14), # 西侧北段
("wall_t_3", "y", 12, -99, -39), # 内部过渡段
("wall_t_4", "x", -39, 12, 16.5), # 西侧中段
("wall_t_5", "y", 16.5, -39, -13), # 内部连接段
("wall_t_6", "x", -13, 13, 16.5), # 短连接段
("wall_t_7", "y", 13, -13, 98), # 内部纵向段
("wall_t_8", "x", 98, 13, 14.5), # 东侧北段
("wall_t_9", "y", 14.5, 98, 115), # 北侧东段
]

墙段布置算法解析:

  • 分段原则:将复杂基坑轮廓分解为简单的直线段
  • 坐标系统:使用(x,y)方向交替,形成连续支护体系
  • 命名规则wall_[位置]_[序号] 便于识别和管理
  • 几何闭合:确保所有墙段首尾相连形成闭合支护体系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def mk_surface(ori, a, b, c):
"""墙段几何生成器 - 统一接口

参数:
- ori: 墙段方向 "x"|"y"
- a: 固定坐标值(x或y)
- b, c: 范围坐标(另一方向的起止点)
"""
return rect_wall_x(a, b, c, Z_TOP, Z_WALL_BOTTOM) if ori == "x" \
else rect_wall_y(a, b, c, Z_TOP, Z_WALL_BOTTOM)

# 批量创建地下连续墙
walls = [
RetainingWall(name=n, surface=mk_surface(o, a, b, c), plate_type=dwall_mat)
for (n, o, a, b, c) in wall_specs
]

for w in walls:
pit.add_structure(StructureType.RETAINING_WALLS.value, w)

5.2 水平支撑系统布置算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 7) 水平支撑系统 - 3道支撑控制墙体位移
braces_L1: List[Beam] = [] # 第一道支撑
braces_L2: List[Beam] = [] # 第二道支撑
braces_L3: List[Beam] = [] # 第三道支撑
buckets = [braces_L1, braces_L2, braces_L3]

def add_brace(name: str, p0: Tuple[float, float, float],
p1: Tuple[float, float, float], bucket: List[Beam]):
"""支撑梁创建辅助函数"""
b = Beam(name=name, line=line_2pts(p0, p1), beam_type=brace_mat)
pit.add_structure(StructureType.BEAMS.value, b)
bucket.append(b)

# 支撑端点坐标数据库
anchor_pts_b = [
[-110, -14], [-105, -14], [-98.5, -12], [-92.5, -12], [-86.5, -12],
[-77.5, -12], [-68.5, -12], [-60.5, -12], [-52.5, -12], [-47, -12],
[-38, -16.5], [-33.7, -16.5], [-27, -16.5], [-20, -16.5], [-9, -13],
[-2.3, -13], [4.5, -13], [12.5, -13], [21.5, -13], [30.5, -13],
[39.5, -13], [48.5, -13], [57.5, -13], [66.5, -13], [75.5, -13],
[84.5, -13], [92.5, -13], [98.5, -14.5], [110, -14.5], [105, -14.5],
[-110, 14], [-105, 14], [105, 14.5], [110, 14.5]
]

anchor_pts_t = [
[-115, -9.2], [-115, -4.39], [-98.5, 12], [-92.5, 12], [-86.5, 12],
[-77.5, 12], [-68.5, 12], [-60.5, 12], [-52.5, 12], [-47, 12],
[-38, 16.5], [-33.7, 16.5], [-27, 16.5], [-20, 16.5], [-9, 13],
[-2.3, 13], [4.5, 13], [12.5, 13], [21.5, 13], [30.5, 13],
[39.5, 13], [48.5, 13], [57.5, 13], [66.5, 13], [75.5, 13],
[84.5, 13], [92.5, 13], [98.5, 14.5], [115, -9.2], [115, -4.39],
[-115, 9.2], [-115, 4.39], [115, 4.39], [115, 9.2]
]

# 支撑深度配置:0.0m, 3.1m, 6.1m(相对地表)
L_depths = (0.0, 3.1, 6.1)

# 三层支撑批量生成算法
for level, depth in enumerate(L_depths):
z_coord = -float(depth) # 转换为负坐标(地下)
for i in range(len(anchor_pts_b)):
add_brace(
f"Brace_{level+1}_{i + 1}", # 命名:支撑_层号_序号
(anchor_pts_b[i][0], anchor_pts_b[i][1], z_coord), # 起点
(anchor_pts_t[i][0], anchor_pts_t[i][1], z_coord), # 终点
buckets[level] # 归属层级
)

支撑系统设计原理:

  • 三道支撑:符合深基坑支护的常规做法
  • 深度配置:0m, 3.1m, 6.1m 形成合理支撑间距
  • 对撑布置:从基坑一侧到另一侧的对角支撑
  • 命名系统:清晰的层级和序号标识(全打包到一个数据里了,实际使用的时候可以一个一个生成,不建议像这样直接做两个端点数组)

第六部分:施工阶段管理系统

6.1 施工阶段配置算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 9) 施工阶段管理系统
# 阶段计算参数配置
st_init = PlasticStageSettings(load_type=LoadType.StageConstruction,
max_steps=120, time_interval=0.5)
st_exc1 = PlasticStageSettings(load_type=LoadType.StageConstruction,
max_steps=140, time_interval=1.0)
st_dewat = PlasticStageSettings(load_type=LoadType.StageConstruction,
max_steps=120, time_interval=0.5)
st_exc2 = PlasticStageSettings(load_type=LoadType.StageConstruction,
max_steps=140, time_interval=1.0)

# 施工阶段定义
ph0 = Phase(name="P0_Initial", settings=st_init) # 初始地应力
ph1 = Phase(name="P2_Dewatering", settings=st_dewat) # 降水阶段
ph2 = Phase(name="P1_Excavate_L1", settings=st_exc1) # 第一层开挖
ph3 = Phase(name="P3_Excavate_L2", settings=st_exc2) # 第二层开挖

# 阶段继承关系建立
ph1.set_inherits(ph0) # 降水阶段继承初始阶段
ph2.set_inherits(ph1) # 开挖阶段继承降水阶段
ph3.set_inherits(ph2) # 最终阶段继承开挖阶段

施工阶段设计原理:

  • 分阶段施工:模拟真实基坑施工顺序
  • 继承关系:每个阶段基于前一阶段的结果继续计算
  • 参数差异化:不同阶段采用不同的计算步长和时间间隔

6.2 土体状态动态管理

1
2
3
4
5
6
7
8
9
10
# 土体状态动态配置 - 基于自动发现的土体分区
if excav_names:
# 降水阶段:开挖区土体设为非激活(不参与计算)
ph1.set_soil_overrides(mk_soil_overrides(excav_names, active=False))

if remain_names:
# 第一层开挖:保留区土体设为刚性(位移约束)
ph2.set_soil_overrides(mk_soil_overrides(remain_names, deformable=False))
# 第二层开挖:保留区土体恢复变形特性
ph3.set_soil_overrides(mk_soil_overrides(remain_names, deformable=True))

土体状态控制逻辑:

  • 初始阶段:所有土体激活且可变形
  • 降水阶段:开挖区土体冻结,模拟降水影响
  • 开挖阶段:保留区土体刚性化,控制位移
  • 最终阶段:恢复真实土体特性

6.3 结构激活时序控制

1
2
3
4
5
# 结构激活时序控制
ph0.activate_structures(walls) # 初始阶段:激活所有地下连续墙
ph0.activate_structures(braces_L1) # 初始阶段:激活第一道支撑
ph1.activate_structures(braces_L2) # 降水阶段:激活第二道支撑
ph3.activate_structures(braces_L3) # 最终阶段:激活第三道支撑

结构激活策略:

  • 地下连续墙:初始即激活,全程参与
  • 水平支撑:随开挖深度逐道安装
  • 降水井:在降水阶段集中激活

6.4 动态水位控制算法

1
2
3
4
5
6
7
8
9
10
11
12
# 阶段水位动态控制
x_min, x_max, y_min, y_max = proj.x_min, proj.x_max, proj.y_min, proj.y_max
water_pts = [
WaterLevel(x_min, y_min, -6.0), # 左下角水位-6m
WaterLevel(x_max, y_min, -6.0), # 右下角水位-6m
WaterLevel(x_max, y_max, -6.0), # 右上角水位-6m
WaterLevel(x_min, y_max, -6.0), # 左上角水位-6m
WaterLevel(0.0, 0.0, -6.0), # 中心点水位-6m(控制点)
]

# 在第二开挖阶段应用降水效果
ph2.set_water_table(WaterLevelTable(water_pts))

水位控制设计:

  • 控制点布局:角点+中心点,形成水位控制网络
  • 水位目标:从-3.5m降至-6.0m,降水2.5米
  • 阶段应用:在开挖阶段体现降水效果

第七部分:模型执行和结果输出系统

7.1 模型构建和执行流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 主执行流程
runner = PlaxisRunner(HOST, PORT, PASSWORD) # 连接PLAXIS计算引擎
pit = assemble_pit(runner=runner) # 组装基坑模型
builder = ExcavationBuilder(runner, pit) # 创建模型构建器

# 钻孔材料重链接(确保材料引用正确)
try:
builder._relink_borehole_layers_to_library()
except Exception:
pass

print("[BUILD] start …")
builder.build() # 执行模型构建(生成PLAXIS几何和网格)
print("[BUILD] done.")

# 土体状态管理
print("[BUILD] Pick up soillayer.")
excava_soils = builder.get_all_child_soils_dict() # 获取所有土体对象
print("[BUILD] Applied the soillayer status for phases.")

# 阶段土体配置应用
print("[APPLY] apply phases …")
pit.phases[1].add_soils(excava_soils["Soil_1_1"]) # 阶段1:配置开挖区土体
pit.phases[3].add_soils(*[excava_soils["Soil_1_1"], excava_soils["Soil_2_1"]]) # 阶段3:配置多区土体
builder.apply_pit_soil_block() # 应用土体状态配置
print("[APPLY] Updated the status of soillayers")

# 执行计算
builder.calculate() # 运行PLAXIS有限元计算

7.2 计算结果提取(提取所有地连墙XYZ三个方向变形)

Plaxis Output中所有ResultTypes中的类型已经全部枚举到了plaxishelper/resulttypes.py中,建议查阅。以下的结果提取代码直接传入枚举类型同时兼容两种传入方式:

  1. 直接传入枚举类型,如Plate.Ux
  2. 直接传入字符串,如"Plate.Ux"(前面的ResultTypes可以省略)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
def export_walls_horizontal_displacement_excel_2(builder: ExcavationBuilder, excel_path: str) -> str:
"""
围护墙水平位移统计摘要导出 - 每墙每相位的最大值统计

与完整数据导出的区别:
- 输出统计摘要而非全量数据
- 重点关注水平位移极值
- 便于快速评估支护效果
- 适合报告和监控使用
"""
import numpy as np
import pandas as pd
from plaxisproxy_excavation.excavation import StructureType
from plaxisproxy_excavation.plaxishelper.resulttypes import Plate

# 1) 项目阶段获取
project_phases = builder.list_project_phases()
if not project_phases:
raise RuntimeError("No project phases found. Ensure phases are defined and calculated.")

# 2) 围护墙对象列表
pit = builder.excavation_object
walls = (getattr(pit, "structures", {}) or {}).get(StructureType.RETAINING_WALLS.value, [])
if not walls:
raise RuntimeError("No retaining walls found in the pit structures.")

def _to_array(v) -> np.ndarray:
"""数据标准化算法 - 增强版本"""
if isinstance(v, list):
return np.asarray(v, dtype=float).ravel()
if isinstance(v, (int, float, np.floating)):
return np.asarray([float(v)], dtype=float)
return np.asarray([], dtype=float)

records = []

# 3) 相位-墙体双层循环
for ph in project_phases:
ph_name = getattr(ph, "name", str(ph))

for wall in walls:
wall_name = getattr(wall, "name", "Wall")

# Ux(水平位移X分量)提取
try:
ux_raw = builder.get_results(structure=wall, leaf=Plate.Ux, phase=ph, smoothing=False)
except Exception as ex:
# 容错处理:记录错误信息
records.append({
"Phase": ph_name, "Wall": wall_name, "NodeCount": 0,
"Ux_max_mm": np.nan, "Uy_max_mm": np.nan, "Uxy_max_mm": np.nan,
"Error": f"Ux query failed: {ex}"
})
continue

# Uy(水平位移Y分量)提取
try:
uy_raw = builder.get_results(structure=wall, leaf=Plate.Uy, phase=ph, smoothing=False)
except Exception as ex:
records.append({
"Phase": ph_name, "Wall": wall_name, "NodeCount": 0,
"Ux_max_mm": np.nan, "Uy_max_mm": np.nan, "Uxy_max_mm": np.nan,
"Error": f"Uy query failed: {ex}"
})
continue

# 数据转换和验证
ux_arr = _to_array(ux_raw)
uy_arr = _to_array(uy_raw)
node_count = int(max(len(ux_arr), len(uy_arr)))

if node_count == 0:
# 无有效数据情况
records.append({
"Phase": ph_name, "Wall": wall_name, "NodeCount": 0,
"Ux_max_mm": np.nan, "Uy_max_mm": np.nan, "Uxy_max_mm": np.nan,
"Error": "No numeric results for Ux/ Uy."
})
continue

# 4) 位移极值计算算法
# 合位移计算:√(Ux² + Uy²)
uxy = np.sqrt(ux_arr**2 + uy_arr**2)

# 统计记录生成
records.append({
"Phase": ph_name,
"Wall": wall_name,
"NodeCount": node_count, # 有效节点数
"Ux_max_mm": float(np.nanmax(np.abs(ux_arr)) * 1000.0), # X向最大位移(mm)
"Uy_max_mm": float(np.nanmax(np.abs(uy_arr)) * 1000.0), # Y向最大位移(mm)
"Uxy_max_mm": float(np.nanmax(np.abs(uxy)) * 1000.0), # 合位移最大值(mm)
})

# 5) 数据整理和输出
df = pd.DataFrame.from_records(records)
if not df.empty:
# 按相位和墙体排序
df = df.sort_values(["Phase", "Wall"], ignore_index=True)

with pd.ExcelWriter(excel_path, engine="openpyxl") as writer:
df.to_excel(writer, index=False, sheet_name="Walls_H_Disp_Summary")
return excel_path

这段代码实现了自动计算结果提取,能够:

  • 快速评估:无需查看全量数据即可了解支护效果
  • 安全监控:重点关注位移极值,判断是否超限
  • 比较分析:不同相位、不同墙体的位移对比
  • 报告生成:适合工程报告和监控报表使用

7.3 结果输出执行流程

1
2
3
4
5
6
7
8
9
10
11
12
# 结果输出执行
print("[TEST] Exporting horizontal wall displacement (all phases) …")
excel_path = "./walls_horizontal_displacements.xlsx"

# 执行完整数据导出
saved = export_walls_horizontal_displacement_excel(builder, excel_path)
print(f"[TEST] Excel saved: {saved}")

# 可选的统计摘要导出(注释状态)
# summary_path = "./walls_displacement_summary.xlsx"
# saved_summary = export_walls_horizontal_displacement_excel_2(builder, summary_path)
# print(f"[TEST] Summary saved: {saved_summary}")

示例小结

这个PLAXIS基坑分析示例体现了完整的岩土工程数值模拟流程:

  1. 前处理:几何建模、材料定义、支护设计
  2. 计算控制:施工阶段管理、边界条件设置
  3. 求解计算:有限元分析、非线性迭代
  4. 后处理:结果提取、数据导出、成果展示(后面会陆续补充VTK可视化相关模块的介绍

第八部分:系统架构深度解析

8.1 面向对象的工程建模架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"""
PLAXIS基坑分析系统 - 面向对象架构

FoundationPit (基坑容器)
├── ProjectInformation (项目信息)
├── MaterialLibrary (材料库)
│ ├── SoilMaterials (土体材料)
│ ├── PlateMaterials (板材料)
│ └── BeamMaterials (梁材料)
├── BoreholeSet (钻孔系统)
│ └── Borehole[] (钻孔数组)
│ └── BoreholeLayer[] (钻孔分层)
├── StructureSystem (结构系统)
│ ├── RetainingWalls[] (围护墙)
│ ├── Beams[] (支撑梁)
│ └── Wells[] (降水井)
└── PhaseSystem (阶段系统)
└── Phase[] (施工阶段)
├── PhaseSettings (计算设置)
├── SoilOverrides (土体状态)
├── ActivatedStructures (激活结构)
└── WaterTable (水位控制)
"""

8.2 计算引擎集成架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"""
计算引擎集成架构:

Python Client (本脚本)
↓ (TCP/IP通信)
PlaxisRunner (运行器)
↓ (COM API)
PLAXIS 3D Engine (计算内核)
↓ (有限元计算)
Result Database (结果数据库)
↓ (数据提取)
Result Analysis (结果分析)
"""

# Runner的核心职责:
# 1. 连接管理:维护与PLAXIS服务器的连接
# 2. 命令执行:将Python对象转换为PLAXIS命令
# 3. 计算控制:管理计算过程和进度
# 4. 结果提取:从PLAXIS数据库读取计算结果

8.3 材料本构模型系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
"""
土体本构模型系统 - 摩尔库仑(Mohr-Coulomb)模型

关键参数体系:
1. 刚度参数:
- E_ref: 参考弹性模量 (15-250 MPa)
- nu: 泊松比 (0.25-0.35)

2. 强度参数:
- c_ref: 参考粘聚力 (5-40 kPa)
- phi: 内摩擦角 (20-40°)
- psi: 剪胀角 (0-6°)

3. 重度参数:
- gamma: 天然重度 (17.5-21.0 kN/m³)
- gamma_sat: 饱和重度 (19.0-22.8 kN/m³)

4. 状态参数:
- e_init: 初始孔隙比 (0.35-0.95)
"""

# 结构材料体系:
# - ElasticPlate: 弹性板单元 (地下连续墙)
# - ElasticBeam: 弹性梁单元 (水平支撑)

8.4 施工阶段有限元分析原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
"""
施工阶段有限元分析原理:

Phase 0: 初始地应力平衡
↓ (重力加载,位移归零)
初始应力场建立

Phase 1: 降水施工
↓ (开挖区土体冻结,水位下降)
降水效应模拟

Phase 2: 第一层开挖
↓ (支撑安装,土体开挖)
支护-开挖相互作用

Phase 3: 第二层开挖
↓ (深层开挖,最终状态)
最终位移场建立

计算特性:
- 每个阶段基于前一阶段结果继续计算
- 考虑土体的应力历史和路径依赖性
- 自动处理接触和非线性行为
"""

写在后面

前处理阶段关键要点

几何建模准确性

1
2
3
4
5
6
7
8
9
10
11
12
# 几何闭合性检查 - 必须确保
def validate_geometry_closure(wall_specs):
"""
检查支护体系几何闭合性要点:
1. 首尾坐标必须重合
2. 相邻墙段必须端点相接
3. 避免几何间隙或重叠
"""
# 实际工程中常见的几何错误:
# - 坐标计算误差导致微小间隙
# - 方向定义错误造成墙体交叉
# - 高程不一致形成错台

几何建模要点:

  • 坐标精度: 使用足够精度(通常0.001m),避免累积误差

  • 方向一致性: 统一采用右手坐标系,确保法线方向正确

  • 高程基准: 明确绝对高程和相对高程的基准面

  • 边界范围: 模型边界应足够大,避免边界效应影响(通常5-10倍基坑尺寸)

材料参数合理性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 土体参数敏感性分析要点
def check_soil_parameter_sensitivity():
"""
土体参数合理性检查清单:
"""
critical_checks = {
"弹性模量E": {
"范围验证": "软土10-50MPa,硬土50-200MPa,岩石>200MPa",
"相关性": "与标贯击数N、剪切波速Vs的经验关系",
"影响因素": "应力水平、加载路径、排水条件"
},
"强度参数": {
"c-φ协调性": "粘性土c高φ低,无粘性土c低φ高",
"试验方法": "UU、CU、CD试验结果的适用性",
"有效应力原理": "总应力与有效应力参数的区分"
},
"渗透参数": {
"降水分析必要性": "k>10⁻⁵m/s需考虑渗流",
"各向异性": "水平渗透系数通常大于垂直系数",
"应力相关性": "渗透系数随有效应力变化"
}
}

材料参数要点:

  • 试验数据支撑:优先使用现场试验和室内试验数据

  • 经验公式验证:与地区经验公式对比验证合理性

  • 参数相关性:注意E与c、φ之间的经验关系

  • 本构模型选择:根据工程问题选择合适的本构模型

土层冻结与激活

由于Plaxis软件中任意一个集合形状都会影响完整土体的完整性(把土体分割成好些个小块),因此在完成了所有的结构建模、网格和阶段创建后,进一步控制开挖土体的状态。不知道是我的软件盗版还是什么原因,相同的代码创建土层和结构之后,每次Plaxis软件划分成的土层编号和名字都不相同,因此很难直接预定义好需要冻结或激活的土层。

我建议在Notebook中来完成建模和阶段创建,而后通过Builder中给出的get_all_child_soils_dict()函数,获取当前所有被划分好的土层,这个土层将会返回一个土层名-土层操作句柄的字典,然后根据GUI反馈的土层名,参考示例代码,在不同的阶段中添加需要冻结的土层(默认所有的土层都是激活状态),来实现不同阶段的自动化开挖。

结果提取

结果提取现已经支持文档中的两种调用方式:

  1. getresults Phase_1 ResultTypes.Soil.Ux "node" True,获取土体所有节点的位移,返回的是一个巨大的数组,可用来代替曲线点的选取,"node"参数可不传,默认返回"node"节点的数据,如果没有就返回"stressnode"的数据,返回的结果可能巨大,包含了所有土体点;
  2. getresults Beam_1 Phase_3 ResultTypes.Beam.X "node" True,获取指定结构的计算结果,返回的是当前结构上所有有限元节点的值,"node"参数可不传,默认返回"node"节点的数据,如果没有就返回"stressnode"的数据。

所有可用的结果对象枚举请参阅:plaxishelper/resulttypes.py


Plaxis代理封装框架——完整的基坑仿真解析(二)
https://www.eatrice.cn/post/PlaxisFrameworkThree/
作者
吃白饭-EatRice
发布于
2025年11月23日
许可协议