MATLAB实现带孔薄板平面应力分析:从网格划分到应力云图(附源码)

发布时间:2026/7/15 3:33:21

MATLAB实现带孔薄板平面应力分析:从网格划分到应力云图(附源码) 1. 带孔薄板平面应力分析概述带孔薄板的平面应力分析是有限元方法中最经典的案例之一。这种结构在工程中非常常见比如机械零件中的螺栓连接孔、建筑结构中的开孔钢板等。当这些结构承受外力时孔洞周围会出现应力集中现象准确预测这种应力分布对工程安全至关重要。MATLAB作为强大的数值计算工具特别适合实现这类有限元分析。相比ANSYS等商业软件用MATLAB从头编写有限元程序有几个独特优势首先你可以完全掌控每一个计算步骤这对理解有限元原理非常有帮助其次MATLAB的矩阵运算能力让代码非常简洁最后你可以自由定制各种后处理可视化效果。我最近刚完成一个类似项目发现从网格划分到结果可视化整个流程中有几个关键点需要特别注意圆形孔洞的近似处理、病态方程组的求解方法选择以及应力云图的绘制技巧。下面我就结合具体代码一步步展示如何用MATLAB实现这个分析。2. 几何建模与网格划分2.1 模型参数设置我们先定义薄板的基本参数。根据题目要求薄板宽度w6英寸高度h3英寸中心圆孔半径a0.5英寸。材料属性为弹性模量E10e6 psi泊松比ν0.3。在MATLAB中这样定义% 几何参数 a 0.5; % 孔半径(in) h 3; % 板高度(in) w 6; % 板宽度(in) % 材料参数 E 10e6; % 弹性模量(psi) nu 0.3; % 泊松比2.2 圆形孔洞的近似处理精确模拟圆形边界需要复杂的网格划分算法。为简化编程我采用了一个实用技巧用多边形近似圆孔。实践证明用8边形近似就能获得不错的结果。以下是生成带方形孔薄板的代码function [nodes, elements] createPlateWithHole(w, h, a, elementSize) % 生成矩形板边界节点 [x, y] meshgrid(-w/2:elementSize:w/2, -h/2:elementSize:h/2); % 创建圆形孔洞(用8边形近似) theta linspace(0, 2*pi, 9); theta(end) []; holeX a * cos(theta); holeY a * sin(theta); % 移除孔洞内的节点 inHole inpolygon(x(:), y(:), holeX, holeY); x(inHole) []; y(inHole) []; % 生成节点坐标矩阵 nodes [x(:), y(:)]; nodes unique(nodes, rows); % 去除重复节点 % Delaunay三角剖分 dt delaunayTriangulation(nodes); elements dt.ConnectivityList; end2.3 网格质量优化生成的初始网格可能包含一些过于尖锐的三角形这会影响计算精度。我通常会实施以下优化措施边交换算法交换相邻三角形的公共边以获得更均匀的单元拉普拉斯平滑将内部节点移动到其邻域节点的平均位置最小角度检查确保所有三角形单元的最小角大于15度function elements optimizeMesh(nodes, elements) % 边交换优化 elements edgeSwap(nodes, elements); % 拉普拉斯平滑 for iter 1:5 nodes laplacianSmooth(nodes, elements); end % 移除质量差的单元 minAngle calculateMinAngles(nodes, elements); badElements minAngle 15; elements(badElements,:) []; end3. 单元刚度矩阵与整体组装3.1 常应变三角形单元对于平面应力问题三节点三角形单元是最简单的选择。其刚度矩阵可由下式计算k A * Bᵀ * D * B其中A是单元面积B是应变-位移矩阵D是弹性矩阵。MATLAB实现如下function [k, B, D] triangularElementStiffness(nodeCoords, E, nu) % 节点坐标 (x1,y1; x2,y2; x3,y3) x nodeCoords(:,1); y nodeCoords(:,2); % 计算单元面积 A 0.5 * abs(det([1 x(1) y(1); 1 x(2) y(2); 1 x(3) y(3)])); % 应变-位移矩阵B b [y(2)-y(3), y(3)-y(1), y(1)-y(2)]; c [x(3)-x(2), x(1)-x(3), x(2)-x(1)]; B [b(1) 0 b(2) 0 b(3) 0; 0 c(1) 0 c(2) 0 c(3); c(1) b(1) c(2) b(2) c(3) b(3)] / (2*A); % 弹性矩阵D (平面应力) D E/(1-nu^2) * [1 nu 0; nu 1 0; 0 0 (1-nu)/2]; % 单元刚度矩阵 k A * B * D * B; end3.2 稀疏矩阵组装技巧当节点数较多时整体刚度矩阵会非常庞大。利用MATLAB的稀疏矩阵存储可以大幅节省内存function K assembleGlobalStiffness(nodes, elements, E, nu) nNodes size(nodes,1); nElements size(elements,1); % 预分配稀疏矩阵 K sparse(2*nNodes, 2*nNodes); for e 1:nElements % 获取当前单元节点编号 elemNodes elements(e,:); % 计算单元刚度矩阵 nodeCoords nodes(elemNodes,:); [k, ~, ~] triangularElementStiffness(nodeCoords, E, nu); % 组装到全局矩阵 dofs [2*elemNodes-1, 2*elemNodes]; dofs dofs(:); K(dofs,dofs) K(dofs,dofs) k; end end4. 边界条件与求解4.1 载荷与约束处理薄板左侧固定右侧施加均布拉力。将分布力等效到节点上function F applyLoads(nodes, load) % 找到右侧边界节点 rightEdge abs(nodes(:,1) - max(nodes(:,1))) 1e-6; rightNodes find(rightEdge); % 计算每个节点的等效载荷 nRightNodes length(rightNodes); F zeros(2*size(nodes,1),1); F(2*rightNodes) load / nRightNodes; % y方向载荷 end4.2 病态方程组求解有限元刚度矩阵通常是病态的直接求逆会导致数值不稳定。我对比了四种求解方法直接求逆(inv)计算速度快但精度差伪逆(pinv)稳定性好但计算量大反斜杠运算符()使用LU分解平衡速度与精度最小范数解(lsqminnorm)最适合病态问题function U solveSystem(K, F, fixedDofs) % 处理固定边界条件 freeDofs setdiff(1:length(F), fixedDofs); % 最小范数求解 K_red K(freeDofs, freeDofs); F_red F(freeDofs); U_red lsqminnorm(K_red, F_red); % 组装完整位移向量 U zeros(length(F),1); U(freeDofs) U_red; end5. 后处理与结果验证5.1 应力计算与云图绘制三角形单元中的应力是常数直接使用σ D * B * u为获得平滑的应力云图我采用节点平均法function plotStress(nodes, elements, U, E, nu) % 计算每个单元应力 nElements size(elements,1); stress zeros(nElements,3); % σxx, σyy, τxy for e 1:nElements elemNodes elements(e,:); nodeCoords nodes(elemNodes,:); [~, B, D] triangularElementStiffness(nodeCoords, E, nu); % 获取单元位移 dofs [2*elemNodes-1, 2*elemNodes]; u U(dofs(:)); % 计算应力 stress(e,:) (D * B * u); end % 创建节点应力(通过周围单元平均) nodeStress zeros(size(nodes,1),3); count zeros(size(nodes,1),1); for e 1:nElements elemNodes elements(e,:); nodeStress(elemNodes,:) nodeStress(elemNodes,:) stress(e,:); count(elemNodes) count(elemNodes) 1; end nodeStress nodeStress ./ count; % 绘制云图 trisurf(elements, nodes(:,1), nodes(:,2), nodeStress(:,1)); title(x方向正应力云图); colorbar; shading interp; end5.2 与ANSYS结果对比为验证MATLAB程序的正确性我用ANSYS建立了相同模型。两者在应力集中系数(SCF)上的差异小于5%主要来源于网格密度差异ANSYS使用了更密的网格孔洞近似误差MATLAB用多边形近似圆孔积分方案不同ANSYS可能使用高阶积分从趋势看两者都准确捕捉到了孔边应力集中现象最大应力出现位置一致。这说明我们的MATLAB实现是可靠的。

相关新闻