ARTICLE DETAIL

资讯详情

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

雨流计数法原理与Python实现:从载荷谱到疲劳寿命分析

雨流计数法原理与Python实现:从载荷谱到疲劳寿命分析 简介雨流计数法又称塔顶法是疲劳设计与疲劳试验中应用最广泛的计数方法之一能够将随机或非平稳的载荷时间历程转化为若干独立的应力-应变循环为机械工程、航空航天、结构工程等领域的疲劳寿命评估提供关键数据。文档系统阐述该方法的原理、实现步骤及力学基础包括载荷离散化、迟滞回线闭合循环提取并说明其与变程对–均值法计数结果一致且能有效处理非对称、非线性循环与多轴载荷简化比单纯峰值法或变程法更贴近材料实际疲劳行为适合机械、航空、土木等领域工程师、科研人员及高年级学生查阅。资源包内含1个doc文件压缩后约213KB内容精炼集中目前已有1105人学习浏览可作为理解载荷谱循环计数、评估结构疲劳损伤的实用参考资料。1. 雨流计数法从一段载荷谱里数出完整循环现场拿到的载荷谱很少是光滑正弦波。风机叶片挥舞弯矩、汽车悬架加速度、起重机吊臂应力都是几秒钟一次波动的随机序列。疲劳分析的第一问题不是算应力而是先回答“这段波形里有几次加载/卸载”。雨流计数法解决的就是这件事把一个任意波形的时序信号拆成一组“谷-峰-谷”的完整循环并保留每个循环的幅值和均值。有了循环表Miner线性累积损伤、S-N曲线估算寿命才有输入。这个方法常用于结构疲劳、焊接寿命、风电叶片设计校核也大量出现在数据分析和可靠性工程的后处理脚本里。读完这篇你能徒手写出一个可运行的雨流计数函数并对结果做验证。2. 雨流计数法的判据迟滞回线、三点法与四点法2.1 先看雨流在数什么能从峰谷画成封闭回路的那些段材料在交变载荷下应力-应变曲线会形成迟滞回线。一个完整的“拉伸-卸载-反向压缩-再卸载”过程会在应力应变平面里画出一个闭合环这个闭合环对应疲劳损伤而开放路径则对应不完整的半循环。雨流计数法的思想就是把这些闭合环找出来。判据上是看折线的局部关系而不是对复杂波形做频域变换所以它对任意随机载荷谱都适用不需要假设周期性。具体做法是把时域信号压缩成峰谷交替的序列再按顺序把点压入一个栈。每当新点进入后检查最近几个点是否形成“被两侧包住”的折段若形成就把该折段认定为一个全循环并取出删除这段数据让前后波形继续配对。下面两节讲最常见的两种检查方式。2.1.1 峰谷序列雨流计数法的输入格式输入不能是原始高频采样点必须先做极值提取。原始信号里的等值点、单调段中间点都不会改变循环结构但会让判据做多余判断。我一般的做法是先删除相邻相等点再保留每个上升/下降趋势的端点得到严格交替的峰值和谷值。第 3 章会给这段可直接运行的代码。2.2 三点法边采边数的在线式判据三点法看栈内最后三个点设三个值依次为 v1、v2、v3。如果 v2 在 v1 与 v3 之间即 v1v2v3 或 v1v2v3说明中间这个折点是可被包含的拐点它没法作为最终极值于是把v1,v2作为一个循环取出删掉 v2让 v1 直接与 v3 配对。这个方法实现简单、内存小适合用在实际设备上边采样边统计比如车桥疲劳测试仪。缺点是它对极端点的保留策略比较激进容易在大循环还没完全落定前就提前拆出小循环导致全循环与半循环分配和标准后处理结果不完全一致。2.3 四点法离线后处理里的主流选择四点法也叫四点判据是离线后处理里更常见的选择。它每次取栈内最后四个点v1、v2、v3、v4。当同时满足“v2 被 v1 和 v3 包住且 v3 被 v2 和 v4 包住”时中间段 v2-v3 确定闭合取出一个全循环再从栈里删掉 v2、v3。删除后原来的 v4 变成新的末端点可能继续和前面的点组成新的四点组合因此能处理“大循环套小循环、小循环被取出后大循环重新配对”的情况比三点法更符合实际损伤累积。我一般用四点法做离线计算三点法留给实时统计场景。两点对比如下判断方式看几个点内存占用适用场景三点法3少量状态实时统计、嵌入式设备四点法4需保留完整栈离线后处理、寿命分析3. 用 Python 复现雨流计数法峰谷提取与四点法实现3.1 第一步把离散波形压缩成峰谷序列先写一个极值提取函数def to_peak_valley(series): # 删除相邻等值点 cleaned [series[0]] for v in series[1:]: if v ! cleaned[-1]: cleaned.append(v) # 删除单调段中间点只保留峰/谷 pts [cleaned[0]] for i in range(1, len(cleaned) - 1): if (cleaned[i - 1] cleaned[i] and cleaned[i] cleaned[i 1]) or ( cleaned[i - 1] cleaned[i] and cleaned[i] cleaned[i 1] ): pts.append(cleaned[i]) pts.append(cleaned[-1]) return pts逻辑说明第一部分去掉等值点避免雨流判据把零幅值变动当作有效转折第二部分保留每个局部极值点因为单调段中间点不会改变任何未来的配对关系。要注意这个函数会把首尾点都保留即使它们不是严格极值。参数说明series 是一维应力或应变序列单位不影响计数结果但后续幅值阈值、损伤计算都需要与材料参数的单位保持一致。返回的 pts 是峰值/谷值交替的列表这是雨流计数唯一需要的输入结构。3.2 第二步用四点法提取循环def rainflow_4point(pts): # pts: 峰谷交替序列 stack [] # 栈内元素为 [value, count] cycles [] # 全循环: (min_value, max_value, count) for v in pts: stack.append([v, 1.0]) while len(stack) 4: v1 stack[-4][0] v2 stack[-3][0] v3 stack[-2][0] v4 stack[-1][0] # 四点判据v2 被 v1/v3 包含v3 被 v2/v4 包含 if (v2 v1 and v3 v4) or (v2 v1 and v3 v4): cycles.append((min(v2, v3), max(v2, v3), 1.0)) del stack[-3:-1] # 删除 v2、v3 else: break return cycles, stack逻辑说明每次推入一个新点就循环检查栈内最后四个点。满足判据时把 v2、v3 之间形成的封闭折段记成一个全循环并从栈中删除这两个点。删除后v4 成为栈的末端点下一次 while 迭代继续检查新的最后四点这样嵌套的小循环被取出后外层大循环能立即重新配对。参数说明栈内元素用[value, count]的形态count 统一取 1.0是为了和后面半循环的 0.5 统一参与 Miner 损伤累加。del stack[-3:-1]删除的是倒数第 3、倒数第 2 两个点也就是 v2、v3不要写成del stack[-2:]那会误删 v4。3.3 第三步从残余栈里拆半循环四点法跑完后栈里剩下的点不能组成任何全循环但这些开放路径仍然是疲劳载荷的一部分通常按半循环处理def residual_half_cycles(stack): half [] for i in range(len(stack) - 1): lo min(stack[i][0], stack[i 1][0]) hi max(stack[i][0], stack[i 1][0]) half.append((lo, hi, 0.5)) # 0.5 表示半个循环 return half逻辑说明残余栈里的相邻点构成一个未封闭的上升或下降段每段贡献 0.5 次循环。首尾两个端点如果参与多段最终在 Miner 计算里会自动配成整数次寿命消耗不需要人为补一个对称波形。参数说明返回元组 (min_value, max_value, 0.5)。后续统计幅值、均值时半循环的计数取值 0.5而不是 1。很多人在这里直接把 0.5 四舍五入高周疲劳计算会偏乐观。3.4 三个容易写错的边界条件栈起始点数太少while len(stack) 4保证了栈不足四点时不判断但如果直接用负数索引访问栈顶必须先确认栈长度防止 IndexError。判据里的等于号v2 v1与v3 v4同时成立时说明有水平段。水平段本身不产生损伤但会影响后续极值配对严谨做法是在峰谷提取阶段把相邻等值点删干净。删除点的位置删除 v2、v3 后之前的 v1 变成新的倒数第三点v4 变成倒数第一点而不是回到循环开始重新压入这一点和栈的常规操作不同。实测时用[0, 2, -1, 3, -2, 1]这类短序列手算一遍最可靠。4. 雨流计数法的参数怎么定门槛、截断与修正4.1 幅值门槛直接影响损伤结果的第一个参数实测信号里总有噪声和小幅抖动。如果不设门槛雨流计数法会数出大量幅值接近零的循环这些循环在 Miner 计算里几乎不消耗寿命却把循环表做得很大也容易掩盖真正的大循环。常见做法是在峰谷提取之后、雨流计数之前把幅值小于阈值的峰谷合并掉。我一般这样合并小峰谷如果相邻两个点的差值小于门槛而且这个点是凸点则直接弹出栈顶让新点与前一个点配对。这样等效于把小幅“驼峰”压平成一次单调变化。阈值选多大要结合载荷量程定常用最大峰谷差的 1%5%。def merge_small_peaks(pts, gate): if len(pts) 2: return pts out [pts[0]] for v in pts[1:]: while len(out) 2 and abs(v - out[-1]) gate: # 只合并“凸点”保留整体趋势 if (out[-2] out[-1] and v out[-1]) or (out[-2] out[-1] and v out[-1]): out.pop() else: break if v ! out[-1]: out.append(v) return out逻辑说明while 条件里abs(v - out[-1]) gate负责识别小幅变化内层 if 判断 out[-1] 是否为凸点。凸点被弹出后v 继续和新的栈顶比较这样连续的小锯齿能被一次合并。不需要合并时把 gate 设成 0函数退化为普通去重。参数说明gate 只影响幅值小于它的局部波动不影响大循环。设置过大超过量程 10%会把真实小载荷事件抹掉设置过小则门槛失去意义。建议先用不合并的结果算一遍把循环表按幅值分布画出来再根据分布曲线里的“噪声平台”边界选 gate。4.2 半循环与平均应力修正雨流计数得到的循环包含幅值和均值两个量。材料 S-N 曲线通常只给交变应力幅但实际载荷集中在某一平均应力附近时必须修正平均应力。常见做法是 Goodman 修正S_ae S_a * S_u / (S_u - S_m)其中 S_a 是循环交变应力幅S_m 是平均应力S_u 是材料极限强度。修正后的等效幅值更高对应寿命更短。修正应该发生在雨流计数之后、Miner 损伤累加之前。半循环在修正时同样按 0.5 计。注意半循环的平均应力不能只用端点平均值要与全循环同样使用两端应力的算术平均即 (v_i v_{i1}) / 2而不是取幅值。4.3 不同载荷工况下的参数配置参考工况门槛平均应力修正半循环处理注意点螺栓预紧/松动1%2% 量程Goodman合并首尾半循环关注最大载荷防止松动焊缝热点应力2%5% 量程Goodman 或 Smith保留所有半循环注意应力集中系数风电叶片弯矩2% 量程Goodman 或 FKM保留半循环长期统计需要按小时聚合一般机械结构5% 量程可忽略或 Goodman半循环按损伤值取半门槛不要超过真实小幅载荷表格里的门槛值一般按载荷量程比例给出。就我接触到的工程数据多数项目用 2%5%很少超过 10%。半循环处理上我建议不主动舍掉半循环因为 Miner 累加时半循环只消耗 0.5 的寿命舍掉会让最终寿命偏大。参数固化之前最好用试验或标准算例做一次对拍。5. 雨流计数法的结果验证Miner 损伤值与三个自查技巧5.1 把循环表换算成 Miner 损伤值雨流计数本身不产生寿命结论它只给循环表。寿命计算还要接上 S-N 曲线N C / S_a^m其中 C、m 由材料试验拟合。把所有循环的损伤累加D Σ (n_i / N_i)D 1 表示疲劳寿命耗尽。下面代码把雨流输出转成损伤值def miner_damage(cycles, C1e12, m4.0, SuNone): D 0.0 for lo, hi, count in cycles: amp (hi - lo) / 2.0 mean (hi lo) / 2.0 if Su: amp amp * Su / (Su - mean) N C / (amp ** m) D count / N return D逻辑说明cycles 里既包含全循环count 为 1.0也包含半循环count 为 0.5。m 通常取 35焊接结构常见取 3一般金属取 5 左右C 的单位与 amp 的单位配套工程上常用 MPa 和“次”。5.2 验证技巧一用 ASTM E1049 的标准算例对拍ASTM E1049 标准里有用于校验计数算法的简单波形。可以拿带符号的折线序列如[0, 1, -2, 3, -4, 5, -2, 0]跑一遍自己的函数把循环表与标准给出的结果对照。第一次实现时建议直接输出完整的 (lo, hi, count) 列表而不是只输出损伤值这样能逐条核对哪一段被错误配对。5.3 验证技巧二波形重构测试把雨流结果按原始顺序重新“播放”一次从第一个点出发见上升段走上升、见下降段走下降所得的包络应能覆盖原始峰谷序列的骨架。如果某个大循环被错误提前关闭重构波形会在中途产生不相连的跳跃肉眼就能看出来。这个测试不验证幅值分布但能快速定位判据方向写反、删除位置错乱这一类实现问题。5.4 验证技巧三符号对称性测试雨流计数法不关心载荷的整体正负只关心峰谷相对差。把原始序列乘 -1 后重新计数循环表应一模一样只是谷和峰互换。这是一个成本极低的回归测试如果你修改过判据跑一遍正反序列比对若结果不同说明判据里混入了绝对值或符号方向判断。建议把“取负后结果一致”写进函数的单元测试每次改动都跑一遍这个测试能拦住绝大多数判据实现错误。本文还有配套的精品资源点击获取
返回列表