1 Star 0 Fork 15

阿柱/ops_utility

forked from yexiang-yan/ops_utility 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
SecMesh.py 25.52 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
"""
SecMesh: A module to mesh the cross-section with triangular fibers
Author: Yexiang Yan
WeChat: yx592715024
"""
import matplotlib.collections
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
import pygmsh
from numpy.typing import ArrayLike
from shapely.geometry import Polygon
class sec_base:
"""
A class for generating fiber-based OpenSees sections based on triangular cells.
"""
def __init__(self):
"""
None
"""
self.outline = None # 截面外轮廓线
self.holes = [] # 将开口初始化为一个空列表
# 保存所有钢筋的信息
self.rebar_coords = [] # 钢筋坐标
self.rebar_areas = [] # 钢筋面积
# 保存所有的网格划分对象
self.mesh_obj = []
# 默认颜色
self.colors = ['#0099e5', '#ffb900', '#6a67ce', '#00a98f']
self.color_rebar = '#be0027'
def add_outline(self, points: ArrayLike):
"""
param points: Coordinates for section profile, List-like, [(x1, y1), (x2, y2),...,(xn,yn)].
clockwise, the beginning and end do not need to be closed.
It can be defined by the corner points of the section, with a straight line segment between points.
Curves need to be subdivided.
"""
self.outline = Polygon(points)
# points = list(self.outline.exterior.coords)
# x, y = self.outline.exterior.xy
def add_outline_circle(self, center=(0, 0), radius=1):
xo, yo = center
alpha = np.linspace(0, 2 * np.pi, 24, endpoint=False)
xcoords = xo + radius * np.cos(alpha)
ycoords = yo + radius * np.sin(alpha)
points = [(x, y) for x, y in zip(xcoords, ycoords)]
self.outline = Polygon(points)
def add_hole(self, points: ArrayLike):
self.holes.append(Polygon(points))
def add_rebar_outline(self, dia, gap, d):
# 偏移获得最外层钢筋线的坐标
outline_rebar = self.outline.buffer(
-d - dia / 2, cap_style=3, join_style=2)
x, y = outline_rebar.exterior.xy
# 根据间距重新划分钢筋点
extern_rebar_points = lines_subdivide(x, y, gap) # 最外层钢筋点
for rebar_xy in extern_rebar_points:
self.rebar_coords.append(rebar_xy)
self.rebar_areas.append(np.pi / 4 * dia ** 2)
def add_rebar_hole(self, dia, gap, d):
# 最内层钢筋点,仅在 holes 定义的情况下才定义
if self.holes: # 如果不是空列表
for hole_line in self.holes:
# 对开口的轮廓进行偏移,以获得最内层钢筋线
inner_rebar_line = hole_line.buffer(
d + dia / 2, cap_style=3, join_style=2)
x, y = inner_rebar_line.exterior.xy
# 根据间距重新划分钢筋点
rebar_xy = lines_subdivide(x, y, gap)
for xy in rebar_xy:
self.rebar_coords.append(xy)
self.rebar_areas.append(np.pi / 4 * dia ** 2)
def add_rebar_line(self, points, dia, gap):
# 处理除最外层与最内层之外的额外的钢筋
rebar_lines = Polygon(points)
x, y = rebar_lines.exterior.xy
# 根据间距重新划分钢筋点
rebar_xy = lines_subdivide(x, y, gap)
for xy in rebar_xy:
self.rebar_coords.append(xy)
self.rebar_areas.append(np.pi / 4 * dia ** 2)
def set_colors(self, colors):
self.colors = colors
def centring(self):
# 将截面移动到形心位置
_, _, sec_property = mesh_geom(self.mesh_obj)
for mesh in self.mesh_obj:
vertices = mesh.points - np.array(sec_property['center']) # 将原点转移到形心位置
mesh.points = vertices
if len(self.rebar_coords) > 0:
self.rebar_coords = np.array(self.rebar_coords)
self.rebar_areas = np.array(self.rebar_areas)
# 将原点转移到形心位置
self.rebar_coords -= np.array(sec_property['center'])
def rotate(self, theta=0):
# 顺时针转动截面
# 先求截面形心
self.rebar_coords = np.array(self.rebar_coords)
theta = theta / 180 * np.pi # 转换成弧度制
self.centring()
for mesh in self.mesh_obj:
vertices = mesh.points
x = vertices[:, 0]
y = vertices[:, 1]
x_rot, y_rot = sec_rotation(x, y, theta) # 将各坐标转动theta
mesh.points[:, 0] = x_rot
mesh.points[:, 1] = y_rot
if len(self.rebar_coords) > 0:
# 将原点转移到形心位置
self.rebar_coords[:, 0], self.rebar_coords[:, 1] = \
sec_rotation(
self.rebar_coords[:, 0], self.rebar_coords[:, 1], theta)
def sec_props(self):
_, _, sec_property = mesh_geom(self.mesh_obj)
return sec_property
def ops_cmds_py(self, secTag: int, matTags: ArrayLike, GJ: float):
"""
生成opensees纤维命令
:param secTag: 截面号
:param matTags: 材料号,列表样
:param GJ: 扭转常数
:return: None
"""
import openseespy.opensees as ops
fiber_center, fiber_area, sec_property = mesh_geom(self.mesh_obj)
fiber_center.append(np.array(self.rebar_coords))
fiber_area.append(np.array(self.rebar_areas))
if len(matTags) != len(fiber_center):
raise ValueError("matTags 必须与截面子区域数相同!此外,若有钢筋,钢筋材料号放在最后")
ops.section('Fiber', secTag, '-GJ', GJ)
i = 0
for centers, areas in zip(fiber_center, fiber_area):
for center, area in zip(centers, areas):
ops.fiber(center[0], center[1], area, matTags[i])
i += 1
def ops_cmds_tcl(self, output_dir: str, secTag: int, matTags: ArrayLike, GJ: float):
"""
生成opensees纤维命令
:param output_dir: 输出目录+文件名
:param secTag: 截面号
:param matTags: 材料号,列表样
:param GJ: 扭转常数
:return: None
"""
fiber_center, fiber_area, sec_property = mesh_geom(self.mesh_obj)
fiber_center.append(np.array(self.rebar_coords))
fiber_area.append(np.array(self.rebar_areas))
if len(matTags) != len(fiber_center):
raise ValueError("matTags 必须与截面子区域数相同!此外,若有钢筋,钢筋材料号放在最后")
with open(output_dir, "w+") as output:
output.write('# This document was created from SecMesh \n\n\n')
output.write(f'set SecTag {secTag}\n')
for i, tag in enumerate(matTags):
output.write(f'set temp_matTag{i + 1} {tag} \n')
temp = "{"
output.write(f'section fiberSec $secTag -GJ {GJ}{temp}; #Define the fiber section\n')
i = 0
for centers, areas in zip(fiber_center, fiber_area):
for center, area in zip(centers, areas):
output.write(f' fiber {center[0]:.3f} {center[1]:.3f} {area:.3f} $temp_matTag{i + 1}\n')
i += 1
output.write('}; # end of fibersection definition')
def mesh_view(self, fill=True, show_mesh_order=True):
"""
:param fill: 是否填充多边形,否则画线框
:param show_mesh_order: 是否显示网格绘制的次序,材料号应与该顺序一致
"""
# matplotlib 绘图
fig, ax = plt.subplots(figsize=(8, 8))
# ax.set_facecolor("#efefef")
# 显示划分图
for i, mesh in enumerate(self.mesh_obj):
vertices = mesh.points
faces = mesh.cells_dict['triangle'] # 每个三角形顶点的号
faces = faces.astype(np.int64)
if not fill:
x = vertices[:, 0]
y = vertices[:, 1]
ax.triplot(x, y, triangles=faces, color=self.colors[i],
lw=1, zorder=0)
if show_mesh_order:
ax.scatter([], [], label=f"mesh #{i + 1}", color=self.colors[i]) # 仅用作图例
else:
x = vertices[:, 0]
y = vertices[:, 1]
ax.triplot(x, y, triangles=faces, lw=1, color='black')
patches = [plt.Polygon(vertices[face_link, :2], True)
for face_link in faces]
coll = matplotlib.collections.PatchCollection(patches,
facecolors=self.colors[i],
edgecolors='black')
ax.add_collection(coll)
if show_mesh_order:
ax.scatter([], [], label=f"mesh #{i + 1}", color=self.colors[i]) # 仅用作图例
patches = [plt.Circle((rebar_xy[0], rebar_xy[1]), np.sqrt(area / np.pi))
for rebar_xy, area in zip(self.rebar_coords, self.rebar_areas)]
coll = matplotlib.collections.PatchCollection(
patches, facecolors=self.color_rebar)
ax.add_collection(coll)
if show_mesh_order:
ax.scatter([], [], label=f"mesh #{len(self.mesh_obj) + 1}", color=self.color_rebar) # 仅用作图例
ax.set_aspect('equal')
ax.set_title('section fiber mesh', fontsize=20)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
ax.legend(fontsize=18, shadow=True, markerscale=3,
title="mesh order", title_fontsize=20)
plt.show()
class SecPlain(sec_base):
def __init__(self):
super(SecPlain, self).__init__()
def mesh(self, mesh_size=None):
"""
"""
if not self.holes: # 如果开口为空列表,即没有开口
with pygmsh.geo.Geometry() as geom:
geom.add_polygon(
list(self.outline.exterior.coords)[:-1],
mesh_size=mesh_size
)
mesh_core = geom.generate_mesh()
# 如果有开口,则为核心区的纤维减去开口部分
else:
with pygmsh.occ.Geometry() as geom:
geom_extern = geom.add_polygon(
list(self.outline.exterior.coords)[:-1],
mesh_size=mesh_size,
)
geom_holes = [
geom.add_polygon(list(hole_line.exterior.coords)[:-1], mesh_size=mesh_size)
for hole_line in self.holes] # 注意可能有多个开口,所以这里holes是一个列表
if len(self.holes) == 1: # 如果只有一个开口,直接减去就可以
geom.boolean_difference(geom_extern, geom_holes[0])
mesh_core = geom.generate_mesh()
else: # 多个开口,先将开口联合,再减去
geom.boolean_difference(
geom_extern, geom.boolean_union(geom_holes))
mesh_core = geom.generate_mesh()
self.mesh_obj.append(mesh_core)
self.rebar_coords = np.array(self.rebar_coords)
self.rebar_areas = np.array(self.rebar_areas)
class SecRC(sec_base):
def __init__(self):
super().__init__()
self.cover_d = None
self.cover_line = None
def add_cover(self, d):
"""
:param d: thickness of cover
"""
self.cover_d = d
self.cover_line = self.outline.buffer(-d, cap_style=3, join_style=2)
def add_rebar_outline(self, dia, gap, d):
sec_base.add_rebar_outline(self, dia, gap, d)
def mesh(self, mesh_size):
with pygmsh.occ.Geometry() as geom:
# 以下进行cover混凝土划分,方式为 整体截面-核心区混凝土部分
geom_extern = geom.add_polygon(
list(self.outline.exterior.coords)[:-1],
mesh_size=mesh_size)
geom_cover = geom.add_polygon(
list(self.cover_line.exterior.coords)[:-1],
mesh_size=mesh_size)
geom.boolean_difference(geom_extern, geom_cover)
mesh_cover = geom.generate_mesh()
if not self.holes: # 如果开口为空列表,即没有开口
with pygmsh.geo.Geometry() as geom:
geom.add_polygon(
list(self.cover_line.exterior.coords)[:-1],
mesh_size=mesh_size
)
mesh_core = geom.generate_mesh()
# 如果有开口,则为核心区的纤维减去开口部分
else:
with pygmsh.occ.Geometry() as geom:
geom_extern = geom.add_polygon(
list(self.cover_line.exterior.coords)[:-1],
mesh_size=mesh_size,
)
geom_holes = [
geom.add_polygon(list(hole_line.exterior.coords)[:-1], mesh_size=mesh_size)
for hole_line in self.holes] # 注意可能有多个开口,所以这里holes是一个列表
if len(self.holes) == 1: # 如果只有一个开口,直接减去就可以
geom.boolean_difference(geom_extern, geom_holes[0])
mesh_core = geom.generate_mesh()
else: # 多个开口,先将开口联合,再减去
geom.boolean_difference(
geom_extern, geom.boolean_union(geom_holes))
mesh_core = geom.generate_mesh()
self.mesh_obj.extend([mesh_cover, mesh_core])
self.rebar_coords = np.array(self.rebar_coords)
self.rebar_areas = np.array(self.rebar_areas)
class SecSRC(SecRC, sec_base):
def __init__(self):
super(SecSRC, self).__init__()
self.bones = []
def add_steel_bone(self, points):
self.bones.append(Polygon(points))
def mesh(self, mesh_size):
with pygmsh.occ.Geometry() as geom:
# 以下进行cover混凝土划分,方式为 整体截面-核心区混凝土部分
geom_extern = geom.add_polygon(
list(self.outline.exterior.coords)[:-1],
mesh_size=mesh_size)
geom_cover = geom.add_polygon(
list(self.cover_line.exterior.coords)[:-1],
mesh_size=mesh_size)
geom.boolean_difference(geom_extern, geom_cover)
mesh_cover = geom.generate_mesh()
# 设置核心混凝土
with pygmsh.occ.Geometry() as geom:
geom_extern = geom.add_polygon(
list(self.cover_line.exterior.coords)[:-1],
mesh_size=mesh_size,
)
geom_bones = [
geom.add_polygon(list(bone_line.exterior.coords)[:-1], mesh_size=mesh_size)
for bone_line in self.bones] # 注意可能有多个开口,所以这里holes是一个列表
if len(self.bones) == 1: # 如果只有一个开口,直接减去就可以
geom.boolean_difference(geom_extern, geom_bones[0])
mesh_core = geom.generate_mesh()
else: # 多个开口,先将开口联合,再减去
geom.boolean_difference(
geom_extern, geom.boolean_union(geom_bones))
mesh_core = geom.generate_mesh()
# 钢骨部分
with pygmsh.occ.Geometry() as geom:
geom_bones = [
geom.add_polygon(list(bone_line.exterior.coords)[:-1], mesh_size=mesh_size)
for bone_line in self.bones]
if len(self.bones) == 1: # 如果只有一个
mesh_bones = geom.generate_mesh()
else:
geom.boolean_union(geom_bones)
mesh_bones = geom.generate_mesh()
self.mesh_obj.extend([mesh_cover, mesh_core] + [mesh_bones])
self.rebar_coords = np.array(self.rebar_coords)
self.rebar_areas = np.array(self.rebar_areas)
class SecSTC(sec_base):
def __init__(self):
super(SecSTC, self).__init__()
self.tube_line = None
self.tube_d = None
def add_steel_tube(self, d):
self.tube_d = d
self.tube_line = self.outline.buffer(-d, cap_style=3, join_style=2)
def add_rebar_tube(self, dia, gap, d):
sec_base.add_rebar_outline(self, dia, gap, d)
def mesh(self, mesh_size):
with pygmsh.occ.Geometry() as geom:
# 以下进行cover混凝土划分,方式为 整体截面-核心区混凝土部分
geom_extern = geom.add_polygon(
list(self.outline.exterior.coords)[:-1],
mesh_size=mesh_size)
geom_tube = geom.add_polygon(
list(self.tube_line.exterior.coords)[:-1],
mesh_size=mesh_size)
geom.boolean_difference(geom_extern, geom_tube)
mesh_tube = geom.generate_mesh()
# 设置核心混凝土
with pygmsh.occ.Geometry() as geom:
geom.add_polygon(
list(self.tube_line.exterior.coords)[:-1],
mesh_size=mesh_size,
)
mesh_core = geom.generate_mesh()
self.mesh_obj.extend([mesh_tube, mesh_core])
self.rebar_coords = np.array(self.rebar_coords)
self.rebar_areas = np.array(self.rebar_areas)
def lines_subdivide(x, y, gap):
"""
The polylines consisting of coordinates x and y are divided by the gap.
"""
x_new = []
y_new = []
for i in range(len(x) - 1):
x1, y1 = x[i], y[i]
x2, y2 = x[i + 1], y[i + 1]
length = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
n = int(length // gap + 1)
x_new.extend(np.linspace(
x1, x2, n + 1, endpoint=True)[:-1].tolist())
y_new.extend(np.linspace(
y1, y2, n + 1, endpoint=True)[:-1].tolist())
new_line = np.column_stack((x_new, y_new, np.zeros(len(x_new))))
return new_line
def sec_rotation(x, y, theta):
"""
Rotate the section coordinates counterclockwise by theta
"""
x_new = x * np.cos(theta) + y * np.sin(theta)
y_new = -x * np.sin(theta) + y * np.cos(theta)
return x_new, y_new
def mesh_geom(mesh_list):
"""
用来计算mesh的几何性质,包括面积,惯性矩等
:param mesh_list: 一个包含pygmsh生成的mesh的列表,即可以包含多个mesh
:return:
"""
fiber_center = []
fiber_area = []
for mesh in mesh_list:
vertices = mesh.points
faces = mesh.cells_dict['triangle']
num = faces.shape[0]
center_points = np.zeros((num, 3)) # 每个三角纤维的中点坐标
areas = np.zeros(num) # 每个三角纤维的面积
for i, face in enumerate(faces):
tag1, tag2, tag3 = face
x1, y1 = vertices[tag1, :2]
x2, y2 = vertices[tag2, :2]
x3, y3 = vertices[tag3, :2]
center_points[i] = (x1 + x2 + x3) / 3, (y1 + y2 + y3) / 3, 0
areas[i] = 0.5 * np.abs(x2 * y3 + x1 * y2 + x3 * y1 - x3 * y2 - x2 * y1 - x1 * y3)
fiber_center.append(center_points)
fiber_area.append(areas)
Centers = np.vstack(fiber_center)
Areas = np.hstack(fiber_area)
# 求总面积
A = np.sum(Areas)
# 求形心坐标
yo = np.sum(Centers[:, 0] * Areas) / A
zo = np.sum(Centers[:, 1] * Areas) / A
# 求截面惯性矩
Iy = np.sum(Centers[:, 1] ** 2 * Areas)
Iz = np.sum(Centers[:, 0] ** 2 * Areas)
# 回转半径
ry = np.sqrt(Iy / A)
rz = np.sqrt(Iz / A)
# 极惯性矩
Ip = Iy + Iz
# 惯性积
Iyz = np.sum(Centers[:, 0] * Centers[:, 1] * Areas)
sec_property = dict(area=A, center=(yo, zo, 0), Iy=Iy,
Iz=Iz, ry=ry, rz=rz, Ip=Ip, Iyz=Iyz)
return fiber_center, fiber_area, sec_property
def ops_sec_vis(ele_tag, sec_num=1, rebar_d=None, color=None):
"""
ele_tag: 要显示截面的所属单元号;
sec_num: 显示单元上的哪个积分点截面,从i段到j段从1开始编号;
rebar_d: 钢筋直径,若想突出显示钢筋,请传入一个标量或列表等,列表则表示有多种钢筋直径。
color: 显示颜色,默认为渐变颜色,其值按与截面中心点的距离变化。
"""
import openseespy.opensees as ops
# 利用eleResponse()命令提取出纤维数据
FiberData = ops.eleResponse(ele_tag, 'section', 'fiberData', sec_num)
# FiberData从第1列至第5列分别为:"yCoord", "zCoord", "area", "stress", "strain"
FiberData = np.array(FiberData).reshape((-1, 5)) # 变形为5列数组
ylocs, zlocs, areas = FiberData[:, 0], FiberData[:, 1], FiberData[:, 2]
# 如下提取出边界与坐标中心
ymin, ymax = np.min(ylocs), np.max(ylocs)
zmin, zmax = np.min(zlocs), np.max(zlocs)
ymean, zmean = np.mean(ylocs), np.mean(zlocs)
# matplotlib 绘图
plt.style.use('fivethirtyeight')
# plt.style.use('ggplot')
fig, ax = plt.subplots(figsize=(8, 8))
patches = [plt.Circle((yloc, zloc), np.sqrt(area / np.pi))
for yloc, zloc, area in zip(ylocs, zlocs, areas)]
coll = matplotlib.collections.PatchCollection(patches, alpha=0.75)
if color is None:
colors = (ylocs - ymean) ** 2 + (zlocs - zmean) ** 2
coll.set_array(colors)
else:
coll.set_color(color)
ax.add_collection(coll)
# 如果包含钢筋
if rebar_d is not None:
rebar_d = np.atleast_1d(rebar_d)
for d in rebar_d:
rebar_area = np.pi * d ** 2 / 4
idx = np.argwhere(np.abs(areas - rebar_area) < 1e-6)
rebar_ys = ylocs[idx]
rebar_zs = zlocs[idx]
rebar_areas = areas[idx]
patches_rebar = [plt.Circle((yloc, zloc), np.sqrt(area / np.pi))
for yloc, zloc, area in zip(rebar_ys, rebar_zs, rebar_areas)]
coll_rebar = matplotlib.collections.PatchCollection(patches_rebar, color='black', alpha=1)
ax.add_collection(coll_rebar)
ax.set_aspect('equal')
ax.set_xlim(ymin * 1.5, ymax * 1.5)
ax.set_ylim(zmin * 1.5, zmax * 1.5)
ax.set_xlabel('y', fontsize=20)
ax.set_ylabel('z', fontsize=20)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
if __name__ == '__main__':
# case 1, 单一材料截面
line = [[0, 0], [1, 0], [2, 1], [1, 2], [0, 1], [0, 0]]
holes = [[(0.5, 0.5), (1.0, 0.5), (1, 1), (0.5, 1)],
[(0.5, 0.5), (1.0, 0.5), (1, 1), (0.5, 1)]]
h = SecPlain()
h.add_outline(line)
h.add_rebar_outline(dia=0.032, gap=0.15, d=0.1)
for hole in holes:
h.add_hole(hole)
h.add_rebar_hole(dia=0.032, gap=0.15, d=0.1)
h.mesh(mesh_size=0.1)
h.rotate(theta=90)
h.centring()
h.mesh_view()
# Case 2 单一材料截面,圆形截面
h = SecPlain()
lines = []
r = 1.2
for angle in np.linspace(0, 2 * np.pi, 24, endpoint=False):
lines.append((r * np.cos(angle), r * np.sin(angle)))
lines2 = []
r = 0.6
for angle in np.linspace(0, 2 * np.pi, 24, endpoint=False):
lines2.append((r * np.cos(angle), r * np.sin(angle)))
h.add_outline(lines)
h.add_rebar_outline(dia=0.032, gap=0.15, d=0.1)
h.add_hole(lines2)
h.mesh(mesh_size=0.2)
# h.centring()
h.mesh_view()
# Case RC 截面
lines = [(-4, 4), (-2, 4), (-2, 2), (2, 2), (2, 4), (4, 4),
(4, -4), (2, -4), (2, -2), (-2, -2), (-2, -4), (-4, -4)]
holes = [[(-3, 1), (-2, 1), (-2, -1), (-3, -1)],
[(3, 1), (2, 1), (2, -1), (3, -1)]]
h = SecRC()
h.add_outline(lines)
h.add_cover(d=0.1)
h.add_rebar_outline(dia=0.06, gap=0.15, d=0.1)
for hole in holes:
h.add_hole(hole)
h.add_rebar_hole(dia=0.06, gap=0.15, d=0.1)
h.mesh(mesh_size=0.4)
h.rotate(theta=0)
h.centring()
h.mesh_view()
# 钢骨混凝土截面
lines = []
r = 4
for angle in np.linspace(0, 2 * np.pi, 6, endpoint=False):
lines.append((r * np.cos(angle), r * np.sin(angle)))
bones = [[(-2, 1), (-1, 1), (-1, -1), (-2, -1)],
[(2, 1), (1, 1), (1, -1), (2, -1)]]
h = SecSRC()
h.add_outline(lines)
h.add_cover(d=0.1)
h.add_rebar_outline(dia=0.06, gap=0.15, d=0.1)
for bone in bones:
h.add_steel_bone(bone)
h.mesh(mesh_size=0.4)
h.rotate(theta=0)
h.centring()
h.mesh_view()
# 钢骨混凝土截面
lines = [(-2, 2), (2, 2), (2, -2), (-2, -2)]
bone = []
r = 1
for angle in np.linspace(0, 2 * np.pi, 24, endpoint=False):
bone.append((r * np.cos(angle), r * np.sin(angle)))
h = SecSRC()
h.add_outline(lines)
h.add_cover(d=0.1)
h.add_rebar_outline(dia=0.06, gap=0.15, d=0.1)
h.add_steel_bone(bone)
h.mesh(mesh_size=0.2)
h.rotate(theta=0)
h.centring()
h.mesh_view()
# 钢管混凝土截面
lines = []
r = 1
for angle in np.linspace(0, 2 * np.pi, 24, endpoint=False):
lines.append((r * np.cos(angle), r * np.sin(angle)))
h = SecSTC()
h.add_outline(lines)
h.add_steel_tube(d=0.02)
h.add_rebar_tube(dia=0.06, gap=0.15, d=0.02)
h.mesh(mesh_size=0.2)
h.rotate(theta=0)
h.centring()
h.mesh_view()
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/wusir1122/ops_utility.git
[email protected]:wusir1122/ops_utility.git
wusir1122
ops_utility
ops_utility
master

搜索帮助