跳转至

说明

损伤定位 — 确定损伤发生在哪个 DOF

通过 COMAC 分析每个自由度的振型变化程度,输出损伤概率向量。

算法 — COMAC

COMAC(Coordinate Modal Assurance Criterion)衡量每个自由度上振型跨模态的一致性:

\[ \operatorname{COMAC}(d) = \frac{\left(\sum_{m=1}^{N_m} \phi_{m,d}^{cur} \cdot \phi_{m,d}^{base}\right)^2} {\sum \left(\phi_{m,d}^{cur}\right)^2 \cdot \sum \left(\phi_{m,d}^{base}\right)^2} \]
  • COMAC = 1:该 DOF 振型未变化
  • COMAC < 1:该 DOF 振型发生变化,值越小变化越大

损伤概率

\[ P(d) = \frac{1 - \operatorname{COMAC}(d)}{\max_k(1 - \operatorname{COMAC}(k))} \]

归一化到 [0, 1],概率最高的 DOF 即为最可能损伤位置。

数据结构

typedef struct {
    int   dof;                         // 最可能损伤的 DOF(无则 -1)
    float prob[TINY_DAMAGE_MAX_DOF];    // 各 DOF 损伤概率 [0, 1]
    float comac_min;                    // 最低 COMAC 值
} tiny_damage_locate_t;

设计详解

1. COMAC vs MAC

MAC COMAC
比较范围 整个振型(所有 DOF 的综合) 单个 DOF
输出 一个标量 [0, 1] 每个 DOF 一个值
用途 模态配对、验证 损伤定位
计算公式 ( \phia^T \phib

COMAC 是 MAC 的"逐自由度版本"——MAC 在所有 DOF 上累加,COMAC 在每个 DOF 上分别累加。

2. 为什么用 double 累加?

double num = 0, den_a = 0, den_b = 0;
for (int m = 0; m < nm; m++) {
    num  += (double)cur->shapes[m][d] * g_baseline.shapes[m][d];
    den_a += (double)cur->shapes[m][d] * cur->shapes[m][d];
    den_b += (double)g_baseline.shapes[m][d] * g_baseline.shapes[m][d];
}

double 累加是为了避免 float 精度损失。当振型值很小(接近 0 的 DOF)时,float 的乘加可能会丢失有效数字。double 提供 15-16 位有效数字 vs float 的 7 位。

3. 概率归一化的作用

\[P(d) = (1 - \operatorname{COMAC}(d)) / \max_k(1 - \operatorname{COMAC}(k))\]

归一化将损伤概率映射到 [0, 1],使得: - 概率最高的 DOF 总是 1.0(最可能损伤位置) - 其他 DOF 的概率相对这个最高值 - 即使所有 COMAC 都接近 1(无损伤),最高值也会被归一化到 1.0

注意:归一化后概率是相对的。当所有 COMAC ≈ 1 时,最高概率 DOF 可能只有很微小的损伤,但归一化后仍显示为 100%。此时应结合 comac_min 判断:若 comac_min > 0.95,即使概率 100% 也不一定真的有损伤。