十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

复合材料梁小应变大位移非线性分析的Python实现

复合材料梁小应变大位移非线性分析的Python实现 简介这份资料围绕非线性复合材料梁理论展开面向具备力学与编程基础的研究人员、工程师尤其是从事直升机叶片等旋转结构设计分析的专业人士。内容涵盖大位移、大旋转但小应变条件下自然弯曲扭转梁的建模思路详解横向剪切变形、扭转翘曲效应与复合材料弹性耦合并结合Python有限元代码实现应变能计算、平衡方程求解等模块帮助读者掌握从理论到编码的完整链路。资源包内含1个PDF文件约880KB便于查阅与打印。该PDF不仅呈现理论推导还配有可运行代码及详细注释并通过铝梁实验对比、直升机叶片设计案例等验证模型适用性可有效支撑实际工程中的模型假设判断与精度提升。目前已有47人学习浏览适合作为非线性梁理论复现、有限元编程实践和复合材料结构设计的参考读物。1. 小应变假设救了复合材料梁建模直升机叶片挥舞、摆振和扭转同时出现时梁端的转角可以到十几度但材料应变往往只有千分之几。对这种“大位移、大旋转、小应变”的复合材料梁直接丢掉几何非线性会低估变形直接上壳单元又会被网格和翘曲细节拖慢。论文提出的框架给出一个很实用的边界位移和转动可以大但应变必须保持小并且小到所有本构关系都能线性使用真正要补的是应变-位移关系中的交叉项、剪切平方项和翘曲引起的扩展-扭转耦合。它面向的是做旋转叶片、细长复合材料梁分析的工程师和研究者。这篇分享不重复推导公式而是把论文拆成一段能跑的Python实现从6×6刚度矩阵、12维平衡ODE到层合板ABD矩阵逐步落到数值结果上。2. 应变-位移关系与刚度矩阵把截面属性写进代码2.1 六维广义应变为什么够用论文处理的是自然弯曲和扭转梁横截面在自身平面内不可变形允许面外翘曲。基于这个假设每个截面的变形状态只需要六个量描述轴向应变epsilon_11、y和z方向横向剪切应变gamma_12、gamma_13、扭转率kappa_1、y和z方向弯曲曲率kappa_2、kappa_3。相应的广义力是轴力、两个剪力、扭矩、两个弯矩。广义应变符号对应广义力截面刚度轴向应变epsilon_11轴力NE·Ay向剪切gamma_12剪力Vykappa_y·G·Az向剪切gamma_13剪力Vzkappa_z·G·A扭转率kappa_1扭矩TG·Jy向曲率kappa_2弯矩MyE·Iyz向曲率kappa_3弯矩MzE·Iz这个六分量体系和经典梁理论写法一致区别在应变-位移关系的非线性程度。论文强调“小应变假设的一致应用”指的是不要在一个表达式里保留二阶位移梯度又在另一个表达式里丢掉它否则能量不一致虚功方程和应变能会对不上。实际实现中轴向应变至少要保留0.5*(dv/dx)^2 0.5*(dw/dx)^2这种来自弧长展开的项因为大位移下梁轴线的伸长量是由横向位移梯度平方贡献的。剪切应变则需要注意截面转动和位移导数的组合v - theta_z、w theta_y的符号错了变形场就会解出一组自相矛盾的截面姿态。2.2 compute_strain非线性应变-位移关系的有限差分实现代码里的compute_strain用np.gradient(u, axis0)对所有位移分量求导再按论文关系组装成6维应变向量。下面代码是原实现的核心段def compute_strain(self, u): 计算应变分量包括非线性项 根据论文中的应变-位移关系 :param u: 位移向量 :return: 应变向量 [epsilon_11, gamma_12, gamma_13, kappa_1, kappa_2, kappa_3] # 对每个位移分量沿梁长方向求导 du np.gradient(u, axis0) # 轴向应变线性项 横向位移梯度平方项几何非线性主要来源 epsilon_11 du[0] 0.5 * (du[1]**2 du[2]**2) # 横向剪切应变截面转角与位移导数的差 gamma_12 du[1] - u[4] # v - theta_z gamma_13 du[2] u[3] # w theta_y # 曲率截面转角沿梁长方向的变化率 kappa_1 du[3] # theta_x kappa_2 du[4] # theta_y kappa_3 du[5] # theta_z return np.array([epsilon_11, gamma_12, gamma_13, kappa_1, kappa_2, kappa_3])代码的逻辑说明du[0]、du[1]、du[2]分别对应轴向和两个横向位移梯度。epsilon_11里的平方项不是可选项而是大位移小应变模型的骨架项来自弧长元 dS² dx² dv² dw² 的泰勒展开。gamma_12写成v - theta_zgamma_13写成w theta_y这组符号约定对应截面法线随转角变化的方向如果改成w - theta_y固定端边界下会出现虚假剪切应变。曲率项直接取转角梯度小应变条件下转角梯度等于曲率是成立的。参数说明这里u的排布顺序是[u, v, w, theta_x, theta_y, theta_z]和后面刚度矩阵的行序一一对应。np.gradient默认用二阶中心差分边界点退化为单侧差分所以网格稀疏时首尾单元的应变会有明显误差我会在两端多加密节点或者只取内部点评估应变能。另外du[1]**2那一段位移单位是m梯度单位是m/m平方后是 m²/m²没有单位问题但数值量级敏感横向位移如果是mm级别平方项比线性项小六个数量级容易被浮点误差吃掉。计算结果低于 1e-12 时先检查位移是不是没换算成米。2.3 6×6对角刚度矩阵与剪切修正系数CompositeBeam的初始化把材料参数和截面参数换算成刚度矩阵K是6×6对角阵self.K np.diag([ self.E * self.A, # 轴向刚度 N self.kappa_y * self.G * self.A, # y向剪切刚度 N self.kappa_z * self.G * self.A, # z向剪切刚度 N self.G * self.J, # 扭转刚度 N·m² self.E * self.Iy, # y向弯曲刚度 N·m² self.E * self.Iz # z向弯曲刚度 N·m² ])对角化意味着轴向、剪切、扭转、弯曲之间没有弹性耦合这是各向同性或正交异性材料在主轴坐标系下的结果。复合材料铺层后B矩阵非零才会出现扩展-扭转、弯曲-扭转耦合那是第4章EnhancedCompositeBeam要处理的事。剪切修正系数乘在G*A上而不是G*J上这是初学实现容易写错的地方kappa只对剪切面积做修正不影响扭转刚度。矩形截面取5/6圆形截面取0.9薄壁圆管常取0.5左右取值错误对短粗梁挠度影响非常明显。J是Saint-Venant扭转常数不是极惯性矩。对矩形薄壁截面J约等于 β·b·t³直接拿I_p代会高估扭转刚度好几倍。示例铝梁给的是J2e-8对应小尺寸实心或薄壁截面先按这个值跑通流程再替换成实际截面的扭转常数。strain_energy方法里的0.5 * epsilon.T self.K epsilon是纯线弹性下的精确表达式如果换成含翘曲项的增强应变应变能密度就不再是单纯的二次型需要按第4章的耦合刚度矩阵处理。3. 平衡方程的ODE求解从12维状态变量到挠度曲线3.1 为什么用12维一阶ODE而不是直接解二阶方程梁的静力平衡方程本质是二阶边值问题。直接对二阶方程做有限差分要引入虚拟节点处理边界把6个位移量和6个截面内力合并成12维状态向量后平衡方程变成一阶常微分方程组scipy.integrate.odeint和solve_bvp都能直接处理这个格式。状态向量的前半部分是广义位移后半部分是广义内力。状态分量含义对应的本构关系u[0]轴向位移udu/dx N/(E·A)u[1]y向位移vdv/dx Vy/(kappa_y·G·A) - theta_zu[2]z向位移wdw/dx Vz/(kappa_z·G·A) theta_yu[3]扭转角theta_xd_theta_x/dx T/(G·J)u[4]绕y转角theta_yd_theta_y/dx My/(E·Iy)u[5]绕z转角theta_zd_theta_z/dx Mz/(E·Iz)u[6:]6个截面内力无分布载荷时为常数表中的dv/dx表达式和compute_strain里的gamma_12 v - theta_z是同一件事v等于剪切角加截面转角。线性化时剪切角由Vy/(kappa_y·G·A)给出所以v Vy/(kappa·G·A) - theta_z。注意theta_z是绕z轴的转角方向约定反了悬臂梁会解出向上翘的物理形态。3.2 equilibrium_equations的实现与分布载荷处理equilibrium_equations把位移-内力的本构关系和内力平衡放在同一个函数里。代码保留了原实现的写法先由内力求位移导数再假设无分布载荷使内力导数为零。def equilibrium_equations(self, u, x): du np.zeros_like(u) # 由内力反解位移梯度本构关系 du[0] u[6] / (self.E * self.A) du[1] u[7] / (self.kappa_y * self.G * self.A) - u[5] du[2] u[8] / (self.kappa_z * self.G * self.A) u[4] du[3] u[9] / (self.G * self.J) du[4] u[10] / (self.E * self.Iy) du[5] u[11] / (self.E * self.Iz) # 假设无分布载荷内力沿梁长不变 du[6:] 0 return du参数和逻辑说明u[6]到u[11]分别是轴力N、剪力Vy、剪力Vz、扭矩T、弯矩My、弯矩Mz它们被假设为常数这是一段没有分布力、没有中间载荷的梁的基本工况。如果实际问题有均布载荷这里要改成dN/dx -p_x、dV_y/dx -p_y、dM_z/dx V_y之类的递推关系把内力从一个截面向下一个截面传递。du[1]里减u[5]是因为v的表达式已经包含剪切角截面转角需要单独列出来du[2]加u[4]对应gamma_13 w theta_y的符号约定。初值u0如果全部给零对应一根既没有位移也没有内力的梁对无载荷工况给出零解一旦边界上施加力就需要从边界条件里注入内力初值这正是solve_static要做的事。3.3 solve_static的边界条件注入与ODE初值问题solve_static把边界条件按fixed、free、force三种键分别处理。fixed把前6个位移置零free把后6个内力置零force把后6个内力设成给定值。这个逻辑本质上是打靶法里的初值猜测而不是严格的边界值求解。def solve_static(self, boundary_conditions): u0 np.zeros(12) for key, value in boundary_conditions.items(): if key fixed: u0[:6] 0 elif key free: u0[6:] 0 elif key force: u0[6:12] value x np.linspace(0, self.L, 100) sol odeint(self.equilibrium_equations, u0, x) return x, solodeint在 x0 处把u0当作初值积分到 xL所以u0实际是左端状态。悬臂梁标准做法是把固定端放在 x0 处u0[:6]0对应固定端位移为0u0[6:12]填入力是因为固定端反力在积分起点就要被确定。注意固定端的内力反力是未知的但作为打靶法初值可以给一个猜测然后通过右端自由端内力为0的残差迭代修正这段代码没有做迭代所以适合线性或弱非线性工况。bc {fixed: True, force: [0, 100, 0, 0, 0, 0]}同时出现fixed和force先执行fixed把位移清零再执行force把初值的剪力设为100N。如果力实际作用在右端u0里放的不能直接是外载荷需要先用力平衡把左端反力算出来否则积分结果会对应一支左端受力的梁而不是右端受力的悬臂梁。网格点太少时非线性项0.5*(du[1]**2 du[2]**2)会因差分误差产生虚假应变能。我一般取至少200个点并观察解在端部有没有振荡odeint使用的 LSODA 会自动切换刚性和非刚性算法但边界层的数值振荡不会被自动滤掉。3.4 铝梁算例数据读法与结果检查示例用1m铝梁、E69GPa、G26GPa、Iz1e-8、A1e-4自由端y方向加100N。求解后solution形状是(100,12)solution[:,1]是 v 沿梁长的位移。# 边界条件: 左端固定右端施加 y 向 100N bc {fixed: True, force: [0, 100, 0, 0, 0, 0]} x, solution aluminum_beam.solve_static(bc) import matplotlib.pyplot as plt plt.plot(x, solution[:, 1], labelDeflection v(x)) plt.xlabel(Beam length (m)) plt.ylabel(Deflection (m)) plt.title(Nonlinear Beam Deflection) plt.legend() plt.grid(True) plt.show()代码说明solution[:,1]对应 v 分量列顺序和状态向量排布一致第0列是轴向位移u。如果把力加到z方向就取solution[:,2]。结果检查有两个角度一是和线性欧拉-伯努利解析解对比1m铝梁、100N、Iz1e-8 的端部挠度 PL³/(3EI_z) ≈ 48.3mm加入横向剪切修正后约增加0.046mm差异超过5%就要检查剪切变形项是不是被意外放大二是把解代回compute_strain看epsilon_11里平方项占线性项的比例超过0.1说明已经偏离小应变前提模型结果只能作为趋势参考。这里 G26e9 是纯铝的典型值对应泊松比约0.33复合材料算例需要按铺层重新计算等效E和G。提示边界条件字典同时传fixed和force时字典遍历顺序决定执行顺序。Python 3.7 字典保持插入顺序先写fixed后写force才能保证梁左端先固定、再注入外力。4. 层合板理论与翘曲函数增强版实现的耦合项落地4.1 从单层Q矩阵到ABD等效刚度EnhancedCompositeBeam不再直接接收 E 和 G而是接收一层一层的材料属性[{E1, E2, G12, nu12, theta, thickness}]每个铺层有自己的材料主轴方向。compute_composite_properties用层合板理论把各层刚度积分成面内刚度 A、耦合刚度 B、弯曲刚度 D再提取等效 E_eff、G_eff 和耦合项。这个步骤对应论文里的弹性耦合特别是扩展-扭转耦合项主要来自 B 矩阵的非对角元。字段含义碳纤维/环氧典型值E1纤维方向拉伸模量140 GPaE2横向模量10 GPaG12面内剪切模量5 GPanu12主泊松比0.28theta铺层角相对梁轴0° / 45° / 90°thickness单层厚度0.125 mm单向复合材料 E1/E2 往往大于10这种高正交异性会让扩展-扭转耦合比金属梁明显得多即使单层角度只有5到10度B矩阵非对角项也会在扭转时贡献出可观的轴向应变。4.2 rotation_matrix与transform_stiffness补上nu21rotation_matrix和transform_stiffness把材料主轴的刚度旋转到全局坐标。原实现里用了nu21但没有给出定义需要按正交异性对称关系补上nu21 nu12 * E2 / E1def transform_stiffness(self, layer, Q): E1, E2 layer[E1], layer[E2] G12 layer[G12] nu12 layer[nu12] nu21 nu12 * E2 / E1 # 正交异性对称关系 Q_local np.array([ [E1/(1-nu12*nu21), nu12*E2/(1-nu12*nu21), 0], [nu12*E2/(1-nu12*nu21), E2/(1-nu12*nu21), 0], [0, 0, G12] ]) # Q 是铺层角的旋转矩阵Q_local 是材料主轴下的平面应力刚度 return Q.T Q_local Q代码逻辑说明Q_local是平面应力状态下的单层刚度矩阵等式nu12*E2/(1-nu12*nu21)和E2/(1-nu12*nu21)来自正交异性材料的柔度矩阵求逆。Q.T Q_local Q完成从材料主轴到全局坐标的旋转这里的Q由rotation_matrix返回内部用c²、s²、c*s组合是工程剪切应变的旋转形式不是张量剪应变的形式。theta在 rotation_matrix 里用np.radians转成弧度如果铺层角度直接传弧度刚度方向会整体错位这是最常见的错误。4.3 enhanced_strain_displacement中的初始曲率交叉项增强版应变-位移关系加入(kx0, ky0, kz0)初始曲率并把翘曲函数warping_function的贡献计入轴向应变def enhanced_strain_displacement(self, u, x): du np.gradient(u, x, axis0) kx0, ky0, kz0 self.initial_curvature # 轴向应变线性项 横向位移梯度平方项 - 初始弯曲引起的几何修正 epsilon_11 du[:,0] 0.5*(du[:,1]**2 du[:,2]**2) \ - ky0*u[:,2] kz0*u[:,1] # 剪切应变包含初始扭转/弯曲带来的耦合项 gamma_12 du[:,1] - u[:,5] kx0*u[:,1] - kz0*u[:,0] gamma_13 du[:,2] u[:,4] kx0*u[:,2] ky0*u[:,0] # 曲率变形曲率加初始曲率 kappa_1 du[:,3] kx0 kappa_2 du[:,4] ky0 kappa_3 du[:,5] kz0 return np.column_stack([epsilon_11, gamma_12, gamma_13, kappa_1, kappa_2, kappa_3])每一项的物理来源epsilon_11里的-ky0*w和kz0*v把自然弯曲梁的初始几何曲率从总曲率中扣除使应变对应的是变形增量而不是总变形gamma_12、gamma_13里的kx0*u1、-kz0*u0项来自截面自身平面内旋转对剪切应变的修正自然扭转梁如果忽视这一项大扭转下会出现虚假剪应变。曲率项kappa_1 theta_x kx0说明总扭转率是初始扭率加变形扭率小应变假设在这个表达式里依然成立但“小”是相对曲率半径而言。若初始曲率半径小于截面尺寸的10倍需要重新审视截面不变形假设。原实现里的compute_warping_strain返回-0.05 * theta1_prime**2 0.01 * theta1**2这是带“示教性质”的简化翘曲模型不是从真实截面翘曲函数求出来的。实际工程中应该用截面分析的翘曲函数比如薄壁闭室或开口截面的扇性坐标再积分得到翘曲刚度代码里留这个接口的意义在于扩展-扭转耦合的轴向应变贡献可以单独开关用来做敏感性对比。4.4 solve_nonlinear_static的BVP残差补完原代码在solve_nonlinear_static的边界条件处理处截断。用solve_bvp补完整时残差函数需要返回状态向量的导数也就是复用equilibrium_equations的内力递推边界条件用固定端位移为0、自由端内力等于外载荷来写def beam_residual(x, y): return equilibrium_equations(y, x) # 12维一阶ODEy 是 (12, n) def beam_bc(ya, yb): left ya[:6] # 固定端位移和转角为0 right yb[6:] - np.array([0, 100, 0, 0, 0, 0]) # 右端剪力100N return np.concatenate([left, right])solve_bvp对初值的敏感性比odeint低但大变形下同样需要接近真实解的初始猜测。我通常先关闭非线性项用线性化版本odeint算一次再把线性解作为solve_bvp的y初值。ya[:6]0不能只约束位移还要约束转角否则刚体转动模态会进入解。右端yb[6:]是自由端内力直接用外载荷向量匹配收敛后取y[1]就是包含剪切变形和几何非线性的 v(x) 曲线与纯欧拉-伯努利解的差异主要来自剪切修正和翘曲项。提示solve_bvp返回的y形状是 (12, n)和odeint的 (n, 12) 正好转置取位移列时要写y[1, :]而不是y[:, 1]。5. 验证扩展-扭转耦合E/G比值与剪切平方项的量级判断5.1 用E/G比值扫描检查耦合项论文强调翘曲引起的扩展-扭转耦合和 E/G 比值相关。代码里coupling_factor self.E / self.G直接乘到耦合项上说明各向同性材料里这个效应相对弱而碳纤维复合材料 E/G 可达20到30同样的扭转率会产生更大的轴向应变。做一个快速扫描验证for eg in [2.6, 10, 20, 30]: beam CompositeBeam(L1.0, Eeg*1e9, G1e9, Iy1e-8, Iz1e-8, J2e-8, A1e-4, kappa_y5/6, kappa_z5/6) eps11 1e-4 # 假定的轴向应变 txp 0.05 # 扭转率 1/m print(eg, beam.extension_twist_coupling(eps11, txp))输出会显示 E/G30 时的耦合应变能约是 E/G2.6 时的11倍以上说明复合材料铺层可以在不增加重量的前提下放大扩展-扭转耦合特性。这个效应在直升机叶片设计中常被用来做气动弹性剪裁通过铺层角调整扭转和挥舞的耦合让叶片在大攻角下自动扭转卸载。若扫描结果不符合这个趋势先检查coupling_factor里是否用了线弹性基本关系G E/(2*(1nu))反推这个关系只对各向同性成立不能直接用于层合板等效属性。5.2 三个落实验证第一铝梁基准测试1m铝梁、100N自由端力、Iz1e-8欧拉-伯努利理论端部挠度 PL³/(3EI_z) ≈ 48.3mm加入剪切修正后增加约0.046mm代码结果应与这个数量级一致。第二把compute_strain的输出拆成线性项和0.5*(dv/dx)^2项观察平方项占比占比超过1%时线性解和解析解开始出现明显偏差此时需要确认是否真的满足小应变前提。第三检查剪切应变平方项当扭转率足够大使得 γ² 和epsilon_11同量级时把它从扩展-扭转耦合项里删掉会让轴向应变预测偏低这正是论文强调不能省略的场合。5.3 剪切平方项什么时候不能省略判断标准很简单先算出截面最大剪切应变 γ再比较 γ² 与轴向应变epsilon_11。对铝梁这类各向同性材料γ 通常为10⁻³量级γ² 为10⁻⁶轴向应变10⁻⁴量级平方项占比不到1%省略影响很小。对高 E/G 的复合材料层合梁同样的扭率下剪切应变更快变大同时轴向应变因泊松和耦合被压低γ² 占比会迅速上升。占比超过5%时建议在compute_strain的轴向应变表达式里保留0.5*(gamma_12² gamma_13²)这类剪切平方项并重新判断小应变假设是否还能一致应用这也决定strain_energy是否仍能用对角刚度矩阵的二次型表达。本文还有配套的精品资源点击获取
返回列表