obsidian_backup/copilot-conversations/20260107_103211__[[Blade]]详细展示公式推导过程.md

93 KiB
Raw Blame History

epoch, modelKey, tags
epoch modelKey tags
1767753131620 gemini-2.5-flash|google
copilot-conversation

user: Blade详细展示公式推导过程 [Timestamp: 2026/01/07 10:32:11]

ai: 该笔记 Blade 详细展示了叶片广义力(包括惯性力、弹性力、阻尼力、重力、气动力)的最终公式形式,但并未提供这些公式从基本原理(如拉格朗日方程或虚功原理)出发的详细推导过程。

以下是对笔记中各项公式的解释及其背后的物理原理:

1. 广义惯性力 (F_{r}^{*}\big|_{B1})

广义惯性力是由于物体运动(包括平动和转动)产生的惯性效应,通过虚功原理或拉格朗日方程推导而来。它通常与系统的质量和加速度有关。

  • 公式 (1):

    
    F_{r}^{*}\big|_{B1} = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, {}^E \, \boldsymbol{v}_{r}^{S1}(r) \cdot {}^E \, \boldsymbol{a}^{S1}(r) \, dr - m^{BldTip} \, {}^E \, \boldsymbol{v}_{r}^{S1}(BldFlexL) \cdot {}^E \, \boldsymbol{a}^{S1}(BldFlexL)
    

    这个公式表示叶片1的广义惯性力它由两部分组成

    1. 积分项: 沿叶片柔性段长度 BldFlexL 的积分,表示叶片分布式质量的惯性力贡献。其中 \mu^{B1}(r) 是单位长度质量,{}^E\boldsymbol{v}_{r}^{S1}(r) 是广义坐标 q_r 对应的虚速度(或模态速度),{}^E\boldsymbol{a}^{S1}(r) 是叶片上点 S1 的绝对加速度。点积表示虚功。
    2. 叶尖质量项: m^{BldTip} 是叶尖质量,{}^E\boldsymbol{v}_{r}^{S1}(BldFlexL){}^E\boldsymbol{a}^{S1}(BldFlexL) 分别是叶尖处的虚速度和加速度。 负号表示惯性力与加速度方向相反D'Alembert 原理)。
  • 公式 (2) 和 (3):

    
    \mu^{B1}(r) = AdjBlMs^{B1} \cdot BMassDen^{B1}(r)
    
    
    m^{B1Tip} = TipMass(1)
    

    这些公式定义了叶片单位长度质量 \mu^{B1}(r) 和叶尖质量 $m^{B1Tip}$,它们可能包含调整系数 (AdjBlMs^{B1}) 或直接来自输入参数 (BMassDen^{B1}(r), TipMass(1))。

  • 公式 (4):

    
    F_{r}^{*}\big|_{B1} = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, {}^{E}\boldsymbol{v}_{r}^{S1}(r) \cdot \left\{ \ldots \right\} dr - m^{B1Tip} {}^{E}\boldsymbol{v}_{r}^{S1}(BldFlexL) \cdot \left\{ \ldots \right\}
    

    此公式展开了加速度 ${}^E\boldsymbol{a}^{S1}(r)$。在多体动力学中,加速度通常可以分解为与广义加速度 \ddot{q}_i 相关的项和与广义速度 \dot{q}_i 相关的项(通常是科里奥利力和离心力项)。

    • 第一行大括号内是与 \ddot{q}_i 相关的项,用于形成质量矩阵。
    • 第二行大括号内是与 \dot{q}_i 相关的项,通常是科里奥利力和离心力,它们来自虚速度对时间的导数。
  • 公式 (5):

    
    \left[C(q,t)\right]_{B1} (\text{Row,Col}) = \int_{0}^{BldFlexL} \mu^{B1}(r) \, {}^{E}\boldsymbol{v}_{\text{Row}}^{S1}(r) \cdot {}^{E}\boldsymbol{v}_{\text{Col}}^{S1}(r) \, dr + m^{B1Tip} {}^{E}\boldsymbol{v}_{\text{Row}}^{S1}(BldFlexL) \cdot {}^{E}\boldsymbol{v}_{\text{Col}}^{S1}(BldFlexL)
    

    这是系统的广义质量矩阵 [C(q,t)]_{B1} 的元素。它通过将公式 (4) 中与 \ddot{q} 相关的项提取出来,并与虚速度 {}^{E}\boldsymbol{v}_{\text{Row}}^{S1}(r) 进行点积积分得到。矩阵的每个元素代表了不同广义坐标之间的惯性耦合。

  • 公式 (6):

    
    \left\{-f(\dot{q},q,t)\right\}_{B1} (\text{Row}) = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, {}^{E}\boldsymbol{v}_{\text{Row}}^{S1}(r) \cdot \left\{ \ldots \right\} dr - m^{B1Tip} {}^{E}\boldsymbol{v}_{\text{Row}}^{S1}(BldFlexL) \cdot \left\{ \ldots \right\}
    

    这是广义科里奥利力和离心力项 ${-f(\dot{q},q,t)}{B1}$。它对应于公式 (4) 中与 \dot{q} 相关的项(即 $\frac{d}{dt} \left( {}^{E}\boldsymbol{v}{i}^{S1}(r) \right) \dot{q}_{i}$),这些项在动力学方程中表现为非线性速度相关力。

2. 广义弹性力 (F_{r}\big|_{ElasticB1})

广义弹性力来源于叶片变形时储存的弹性势能。

  • 公式 (7):

    
    F_{r}\big|_{ElasticB1} = -\frac{\partial V'^{B1}}{\partial q_r}
    

    这是弹性力的基本定义,即弹性势能 V'^{B1} 对广义坐标 q_r 的负偏导数。

  • 公式 (8):

    
    \left. F_{r} \right|_{ElasticB1} =
    \begin{cases}
    - {k'}_{11}^{B1F} q_{B1F1} - {k'}_{12}^{B1F} q_{B1F2}
     & \text{for } r = B1F1 \\
    - {k'}_{11}^{B1E} q_{B1E1}
     & \text{for } r = B1E1 \\
    - {k'}_{21}^{B1F} q_{B1F1} - {k'}_{22}^{B1F} q_{B1F2}
     & \text{for } r = B1F2 \\
    0
     & \text{otherwise}
    \end{cases}
    

    此公式给出了具体的广义弹性力表达式,它与广义位移 q 呈线性关系,并通过广义刚度 k' 连接。这表明叶片被建模为具有多个模态的弹性体,其中 B1F1, B1F2 代表挥舞方向的模态, B1E1 代表摆振方向的模态。

  • 公式 (9) 和 (10):

    
    {k'}_{ij}^{B1F} = \sqrt{FlStTunr^{B1}(i) \, FlStTunr^{B1}(j)} \int_{0}^{BldFlexL} EI^{B1F}(r) \frac{d^2 \phi_i^{B1F}(r)}{dr^2} \frac{d^2 \phi_j^{B1F}(r)}{dr^2} dr
    
    
    EI^{B1F}(r) = AdjFlSt^{B1} \cdot FlpStff^{B1}(r)
    

    这些公式定义了挥舞方向的广义刚度 ${k'}_{ij}^{B1F}$。它通过对叶片弯曲刚度 EI^{B1F}(r) 和模态函数 \phi 的二阶导数(曲率)进行积分得到。这来源于梁的弯曲应变能公式 $V = \frac{1}{2} \int EI (\frac{d^2w}{dx^2})^2 dx$。

  • 公式 (11) 和 (12):

    
    {k'}_{11}^{B1E} = \int_{0}^{BldFlexL} EI^{B1E}(r) \left[ \frac{d^2 \phi_{1}^{B1E}(r)}{dr^2} \right]^2 dr
    
    
    EI^{B1E}(r) = AdjEdSt^{B1} \cdot EdgStff^{B1}(r)
    

    这些公式定义了摆振方向的广义刚度 ${k'}_{11}^{B1E}$,与挥舞方向的推导类似。

3. 广义阻尼力 (F_r\big|_{DampB1})

广义阻尼力用于耗散系统能量,通常与广义速度成正比。这里采用了瑞利阻尼技术。

  • 公式 (13):

    
    \left. F_r \right|_{DampB1} =
    \begin{cases}
    -\frac{\zeta_1^{B1F} {k'}_{11}^{B1F}}{\pi f^{\prime B 1 F}_1} \dot{q}_{B1F1} - \frac{\zeta_2^{B1F} {k'}_{12}^{B1F}}{\pi f^{\prime B 1 F}_2} \dot{q}_{B1F2} & \text{for } r = B1F1 \\
    -\frac{\zeta_1^{B1E} {k'}_{11}^{B1E}}{\pi f^{\prime B 1 E}_1} \dot{q}_{B1E1} & \text{for } r = B1E1 \\
    -\frac{\zeta_1^{B1F} {k'}_{21}^{B1F}}{\pi f^{\prime B 1 F}_1} \dot{q}_{B1F1} - \frac{\zeta_2^{B1F} {k'}_{22}^{B1F}}{\pi f^{\prime B 1 F}_2} \dot{q}_{B1F2} & \text{for } r = B1F2 \\
    0 & \text{otherwise}
    \end{cases}
    

    此公式给出了广义阻尼力,它与广义速度 \dot{q} 呈线性关系。阻尼系数由结构阻尼比 $\zeta$、广义刚度 k' 和固有频率 f' 确定。瑞利阻尼假设阻尼矩阵与质量矩阵和/或刚度矩阵成比例。

  • 公式 (14) 和 (15):

    
    f_i^{\prime B1F} = \frac{1}{2\pi} \sqrt{\frac{k_{ii}^{\prime B1F}}{m_{ii}^{\prime B1F}}}
    
    
    f_i^{\prime B1E} = \frac{1}{2\pi} \sqrt{\frac{k_{ii}^{\prime B1E}}{m_{ii}^{\prime B1E}}}
    

    这些是单自由度系统固有频率的经典公式,其中 k_{ii}^{\prime} 是广义刚度, m_{ii}^{\prime} 是广义质量。

  • 公式 (16) 和 (17):

    
    m_{ij}^{\prime B1F} = \int_{0}^{BldFlexL} \mu^{B1}(r) \phi_i^{B1F}(r) \phi_j^{B1F}(r) \, dr
    
    
    m_{11}^{\prime B1E} = \int_{0}^{BldFlexL} \mu^{B1}(r) \left[ \phi_1^{B1E}(r) \right]^2 dr
    

    这些公式定义了广义质量 $m_{ij}^{\prime}$,它通过对叶片单位长度质量 \mu^{B1}(r) 和模态函数 \phi 的乘积进行积分得到。这来源于动能公式 $T = \frac{1}{2} \int \mu \dot{w}^2 dx$。

  • 公式 (18), (19), (20):

    
    [C(q,t)]|_{ElasticB1} = 0 \quad \text{and} \quad [C(q,t)]|_{DampB1} = 0
    
    
    \left. \left\{ -f(\dot{q},q,t) \right\} \right|_{ElasticB1} = \begin{pmatrix} \vdots \\ \vdots \\ \vdots \\ -k_{11}^{\prime B1F} q_{B1F1} - k_{12}^{\prime B1F} q_{B1F2} \\ -k_{11}^{\prime B1E} q_{B1E1} \\ -k_{21}^{\prime B1F} q_{B1F1} - k_{22}^{\prime B1F} q_{B1F2} \\ \vdots \\ \vdots \\ \vdots \end{pmatrix}
    
    
    \left. \left\{ -f(\dot{q},q,t) \right\} \right|_{DampB1} = \begin{pmatrix} \vdots \\ \vdots \\ \vdots \\ -\frac{\zeta_1^{B1F} k_{11}^{\prime B1F}}{\pi f_1^{\prime B1F}} \dot{q}_{B1F1} - \frac{\zeta_2^{B1F} k_{12}^{\prime B1F}}{\pi f_2^{\prime B1F}} \dot{q}_{B1F2} \\ -\frac{\zeta_1^{B1E} k_{11}^{\prime B1E}}{\pi f_1^{\prime B1E}} \dot{q}_{B1E1} \\ -\frac{\zeta_1^{B1F} k_{21}^{\prime B1F}}{\pi f_1^{\prime B1F}} \dot{q}_{B1F1} - \frac{\zeta_2^{B1F} k_{22}^{\prime B1F}}{\pi f_2^{\prime B1F}} \dot{q}_{B1F2} \\ \vdots \\ \vdots \\ \vdots \end{pmatrix}
    

    这些公式总结了弹性力和阻尼力在动力学方程中的作用。它们不贡献于广义质量矩阵 $[C(q,t)]$,而是作为广义力向量 \{-f(\dot{q},q,t)\} 的一部分出现。

4. 广义重力 (F_{r}\big|_{GravB1})

广义重力来源于叶片在重力场中的势能。

  • 公式 (21):

    
    F_{r}\big|_{GravB1} = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, \boldsymbol{g}^{E}\boldsymbol{v}_{r}^{S1}(r) \cdot \boldsymbol{{z}}_2 \, dr - m^{B1Tip} \boldsymbol{g}^{E}\boldsymbol{v}_{r}^{S1}(BldFlexL) \cdot \boldsymbol{{z}}_2
    

    此公式表示广义重力,它由叶片分布式质量和叶尖质量的重力贡献组成。其中 \boldsymbol{g} 是重力加速度,\boldsymbol{z}_2 是重力方向的单位向量。点积表示重力在虚位移方向上所做的虚功。

  • **公式 (22) 和 (23):力加速度,\boldsymbol{z}_2 是重力方向的单位向量。点积表示重力在虚位移方向上所做的虚功。

  • **公式 (22) 和 (23): [Timestamp: 2026/01/07 10:32:38]

user: 继续生成 [Timestamp: 2026/01/07 10:52:38]

ai: 好的,我将继续对笔记 Blade 中剩余的公式进行详细解释。

4. 广义重力 (F_{r}\big|_{GravB1}) (续)

  • 公式 (22):

    
    [C(q,t)]|_{GravB1} = 0
    

    这个公式表明广义重力不贡献于广义质量矩阵 $[C(q,t)]$。重力是一个保守力,其作用只与位置有关,不直接与加速度相关。

  • 公式 (23):

    
    \left\{ -f(\dot{q}, q, t) \right\}|_{GravB1} (\text{Row}) = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, g \, {}^E\boldsymbol{v}_{Row}^{S1}(r) \cdot \boldsymbol{z}_2 \, dr - m^{B1Tip} \, g \, {}^E\boldsymbol{v}_{Row}^{S1}(BldFlexL) \cdot \boldsymbol{z}_2
    

    此公式给出了广义重力项 ${-f(\dot{q}, q, t)}|_{GravB1}$。它表示重力在广义坐标方向上的投影。其中 g 是重力加速度的大小,\boldsymbol{z}_2 是重力方向的单位向量。这个项是广义力向量的一部分,在动力学方程中作为外力项出现。

5. 广义气动力 (\boldsymbol{F}_r \big|_{AeroB1})

广义气动力是由于叶片与空气相互作用产生的力,包括升力、阻力以及气动俯仰力矩。

  • 公式 (24):

    
    \boldsymbol{F}_r \big|_{AeroB1} = \int_{0}^{BldFlexL} \left[ {}^E\boldsymbol{v}_r^{S1}(r) \cdot \boldsymbol{F}_{AeroB1}^{S1}(r) + {}^E\boldsymbol{\omega}_r^{M1}(r) \cdot \boldsymbol{M}_{AeroB1}^{M1}(r) \right] dr + {}^E\boldsymbol{v}_r^{S1}(BldFlexL) \cdot \boldsymbol{F}_{TipDragB1}^{S1}(BldFlexL)
    

    这个公式表示叶片1的广义气动力它由三部分组成

    1. 分布式气动力项: 沿叶片柔性段长度 BldFlexL 的积分项。
      • {}^E\boldsymbol{v}_r^{S1}(r) \cdot \boldsymbol{F}_{AeroB1}^{S1}(r): 表示单位展向长度上的气动力 \boldsymbol{F}_{AeroB1}^{S1}(r) 在广义坐标 q_r 对应的虚速度 {}^E\boldsymbol{v}_r^{S1}(r) 方向上所做的虚功。
      • {}^E\boldsymbol{\omega}_r^{M1}(r) \cdot \boldsymbol{M}_{AeroB1}^{M1}(r): 表示单位展向长度上的气动俯仰力矩 \boldsymbol{M}_{AeroB1}^{M1}(r) 在广义坐标 q_r 对应的虚角速度 {}^E\boldsymbol{\omega}_r^{M1}(r) 方向上所做的虚功。
    2. 叶尖阻力项: {}^E\boldsymbol{v}_r^{S1}(BldFlexL) \cdot \boldsymbol{F}_{TipDragB1}^{S1}(BldFlexL) 表示叶尖阻力 \boldsymbol{F}_{TipDragB1}^{S1}(BldFlexL) 在叶尖虚速度方向上所做的虚功。

    物理意义: 广义气动力是通过将作用在叶片上的实际气动力和气动扭矩(包括分布式载荷和叶尖载荷)投影到各个广义坐标的虚位移(或虚速度)方向上得到的。这符合虚功原理,即广义力等于实际力在虚位移上所做的虚功。

    其中描述:

    • F_{AeroB1}^{S1}(r)M_{AeroB1}^{M1}(r) 是作用于叶片1上点S1处的单位展向长度上的气动力和气动俯仰力矩。
    • M_{AeroB1}^{M1}(r) 可以包含直接气动俯仰力矩如由翼型弯度引起的Cm和由气动升力/阻力作用在偏离叶片元素质心的位置所产生的力矩。
  • 公式 (25):

    
    [C(q,t)]|_{AeroB1} = 0
    

    这个公式表明广义气动力不贡献于广义质量矩阵 $[C(q,t)]$。气动力通常被视为外力,其大小和方向取决于叶片的运动状态(速度、攻角等),但不直接与加速度线性相关以形成质量矩阵的项。

  • 公式 (26):

    
    \left\{ -f(\dot{q}, q, t) \right\}|_{AeroB1} (\text{Row}) = \int_{0}^{BldFlexL} \left[ {}^E\boldsymbol{v}_{Row}^{S1}(r) \cdot \boldsymbol{F}_{AeroB1}^{S1}(r) + {}^E\boldsymbol{\omega}_{Row}^{M1}(r) \cdot \boldsymbol{M}_{AeroB1}^{M1}(r) \right] dr + {}^E\boldsymbol{v}_{Row}^{S1}(BldFlexL) \cdot \boldsymbol{F}_{TipDragB1}^{S1}(BldFlexL)
    

    此公式给出了广义气动力项 ${-f(\dot{q}, q, t)}|_{AeroB1}$。它与公式 (24) 的形式相同,表明广义气动力作为广义力向量的一部分,在动力学方程中作为外力项出现。气动力通常是速度和位移的复杂非线性函数。

总结

这份笔记 Blade 详细列出了风力机叶片动力学模型中各种广义力的最终表达式。这些表达式是基于多体动力学理论(如虚功原理或拉格朗日方程)推导而来的。

推导过程的通用步骤通常包括:

  1. 定义系统和广义坐标: 确定叶片的柔性模态(挥舞、摆振)以及其他自由度(如桨距、偏航等),并选择一组广义坐标 q_i 来描述系统的运动。
  2. 建立运动学关系: 确定叶片上任意一点的位移、速度和加速度与广义坐标及其导数之间的关系。这通常涉及坐标系的转换和模态函数的应用。
  3. 计算动能和势能:
    • 动能 (T): 积分叶片分布式质量和叶尖质量的动能。
    • 弹性势能 (V_{elastic}): 积分叶片变形(弯曲、扭转)产生的应变能。
    • 重力势能 (V_{gravity}): 积分叶片分布式质量和叶尖质量在重力场中的势能。
  4. 应用拉格朗日方程或虚功原理:
    • 拉格朗日方程: \frac{d}{dt}\left(\frac{\partial T}{\partial \dot{q}_r}\right) - \frac{\partial T}{\partial q_r} + \frac{\partial V}{\partial q_r} = Q_r
      • 其中 Q_r 是非保守广义力(如阻尼力、气动力)。
      • 通过对动能和势能求导,可以得到广义惯性力、广义弹性力和广义重力。
    • 虚功原理: \delta W = \sum_i (\boldsymbol{F}_i - m_i \boldsymbol{a}_i) \cdot \delta \boldsymbol{r}_i + \sum_j (\boldsymbol{M}_j - \boldsymbol{H}_j) \cdot \delta \boldsymbol{\theta}_j = 0
      • 将所有主动力、惯性力、阻尼力等在虚位移上所做的虚功求和,并令其为零。通过提取广义坐标前的系数,可以得到广义力。

笔记中给出的公式是这些推导过程的最终结果,它们将叶片的物理特性(质量分布、刚度分布、阻尼比、模态形状)与广义坐标及其导数联系起来,形成了用于风力机叶片动力学分析的运动方程。 [Timestamp: 2026/01/07 10:52:51]

user: 基于凯恩方程原理,对上述公式做重新解释 [Timestamp: 2026/01/07 10:55:38]

ai: 这份笔记 Blade 中展示的公式与凯恩方程Kane's Equations原理高度一致。凯恩方程是一种系统地推导复杂机械系统运动方程的方法尤其适用于多体系统和柔性体动力学。其核心思想是将系统的运动方程表示为广义主动力 (F_r) 和广义惯性力 (F_r^*) 之和为零的形式:

F_r + F_r^* = 0 \quad (r = 1, \ldots, n)

其中,n 是广义坐标的数量。

下面我将基于凯恩方程的原理,对笔记中的各项公式进行重新解释:

凯恩方程基础概念回顾

  1. 广义坐标 (q_r) 和广义速度 (u_r): 描述系统构型的独立变量及其时间导数。在笔记中,广义坐标 q_r 及其时间导数 \dot{q}_r 被直接用作广义速度。
  2. 偏速度 (Partial Velocity) 和偏角速度 (Partial Angular Velocity): 对于系统中的任意一点或刚体,其绝对速度 \boldsymbol{v} 和绝对角速度 \boldsymbol{\omega} 可以表示为广义速度的线性组合: \boldsymbol{v} = \sum_r \boldsymbol{v}_r \dot{q}_r + \boldsymbol{v}_t \boldsymbol{\omega} = \sum_r \boldsymbol{\omega}_r \dot{q}_r + \boldsymbol{\omega}_t 其中,\boldsymbol{v}_r\boldsymbol{\omega}_r 分别是该点或刚体相对于广义速度 \dot{q}_r 的偏速度和偏角速度。笔记中的 {}^E\boldsymbol{v}_{r}^{S1}(r){}^E\boldsymbol{\omega}_{r}^{M1}(r) 正是这些偏速度和偏角速度。
  3. 广义主动力 (F_r): 所有作用在系统上的主动力(如弹性力、阻尼力、重力、气动力等)在对应偏速度和偏角速度方向上的投影之和。 F_r = \sum_{k} (\boldsymbol{v}_r^{(k)} \cdot \boldsymbol{R}^{(k)} + \boldsymbol{\omega}_r^{(k)} \cdot \boldsymbol{M}^{(k)}) 其中 \boldsymbol{R}^{(k)}\boldsymbol{M}^{(k)} 是作用在 k 点的力和力矩。
  4. 广义惯性力 (F_r^*): 所有作用在系统上的惯性力(由质量和加速度引起)在对应偏速度和偏角速度方向上的投影之和。 F_r^* = \sum_{k} (\boldsymbol{v}_r^{(k)} \cdot \boldsymbol{R}^{*(k)} + \boldsymbol{\omega}_r^{(k)} \cdot \boldsymbol{M}^{*(k)}) 其中 \boldsymbol{R}^{*(k)} = -m^{(k)} \boldsymbol{a}^{(k)} 是惯性力,\boldsymbol{M}^{*(k)} 是惯性力矩。

笔记公式的凯恩方程解释

1. 广义惯性力 (F_{r}^{*}\big|_{B1})

凯恩方程中,广义惯性力是系统各部分惯性力在偏速度方向上的投影之和。

  • 公式 (1):

    
    F_{r}^{*}\big|_{B1} = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, {}^E \, \boldsymbol{v}_{r}^{S1}(r) \cdot {}^E \, \boldsymbol{a}^{S1}(r) \, dr - m^{BldTip} \, {}^E \, \boldsymbol{v}_{r}^{S1}(BldFlexL) \cdot {}^E \, \boldsymbol{a}^{S1}(BldFlexL)
    

    这个公式直接体现了凯恩方程中广义惯性力的定义。

    • {}^E \, \boldsymbol{v}_{r}^{S1}(r) 是叶片上径向位置 r 处点 S1 相对于广义坐标 q_r偏速度
    • \mu^{B1}(r) \, dr 是微分质量元素。
    • \mu^{B1}(r) \, {}^E \, \boldsymbol{a}^{S1}(r) \, dr 是作用在微分质量元素上的惯性力(质量乘以加速度)。
    • 点积 \boldsymbol{v}_r \cdot (m \boldsymbol{a}) 表示惯性力在偏速度方向上的投影。负号表示惯性力与加速度方向相反。
    • 积分项处理分布式质量的贡献,第二项处理叶尖集中质量的贡献。
  • 公式 (4): 此公式将绝对加速度 {}^E\boldsymbol{a}^{S1}(r) 分解为与广义加速度 \ddot{q}_i 相关的项和与广义速度 \dot{q}_i 相关的项。

    • \ddot{q}_i 相关的项用于构建广义质量矩阵。
    • \dot{q}_i 相关的项(涉及偏速度对时间的导数 $\frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(r) \right)$)代表了科里奥利加速度和离心加速度等速度相关效应。这些项在凯恩方程中构成了广义惯性力中与速度相关的部分。
  • 公式 (5) - 广义质量矩阵 [C(q,t)]_{B1}: 在凯恩方程中,当广义惯性力 F_r^* 被写成 \sum_s M_{rs} \ddot{q}_s + G_r 的形式时,[C(q,t)]_{B1} 正是其中的 M_{rs} 元素,即广义质量矩阵。它是由偏速度与偏速度的点积(加权质量)形成的,反映了系统在加速时的惯性耦合。

  • 公式 (6) - 速度相关惯性力 \{-f(\dot{q},q,t)\}_{B1}: 此项对应于凯恩方程中广义惯性力 F_r^*G_r 部分,包含了所有速度相关的惯性效应,如科里奥利力和离心力。这些力是非线性的,并且在运动方程中作为广义力向量的一部分出现。

2. 广义弹性力 (F_{r}\big|_{ElasticB1})

  • 公式 (7): $F_{r}\big|_{ElasticB1} = -\frac{\partial V'^{B1}}{\partial q_r}$。 在凯恩方程中,保守力(如弹性力)的广义力可以通过其势能 V' 对广义坐标的负偏导数来计算。这是一种将保守力纳入广义主动力 F_r 的标准方法。
  • 公式 (8): 提供了具体的线性弹性广义力表达式。这些力直接贡献于广义主动力 $F_r$。
  • 公式 (9)-(12): 定义了广义刚度 $k'$,这些是弹性力表达式中的系数,来源于叶片的材料特性和模态形状。

3. 广义阻尼力 (F_r\big|_{DampB1})

  • 公式 (13): 提供了广义阻尼力的表达式。 在凯恩方程中,阻尼力是非保守力,它们直接作为广义主动力 F_r 的一部分。此处的瑞利阻尼假设使得阻尼力与广义速度成正比。
  • 公式 (14)-(17): 定义了固有频率 f' 和广义质量 $m'$,这些参数用于计算阻尼系数,进而确定广义阻尼力。

4. 广义重力 (F_{r}\big|_{GravB1})

  • 公式 (21):
    
    F_{r}\big|_{GravB1} = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, \boldsymbol{g}^{E}\boldsymbol{v}_{r}^{S1}(r) \cdot \boldsymbol{{z}}_2 \, dr - m^{B1Tip} \boldsymbol{g}^{E}\boldsymbol{v}_{r}^{S1}(BldFlexL) \cdot \boldsymbol{{z}}_2
    
    此公式计算了广义重力。
    • \mu^{B1}(r) \, \boldsymbol{g} 是微分质量元素上的重力。
    • {}^E\boldsymbol{v}_{r}^{S1}(r) \cdot \boldsymbol{{z}}_2 表示重力在偏速度方向上的投影。
    • 这直接符合凯恩方程中广义主动力 F_r 的定义,即主动力在偏速度方向上的投影。

5. 广义气动力 (\boldsymbol{F}_r \big|_{AeroB1})

  • 公式 (24):
    
    \boldsymbol{F}_r \big|_{AeroB1} = \int_{0}^{BldFlexL} \left[ {}^E\boldsymbol{v}_r^{S1}(r) \cdot \boldsymbol{F}_{AeroB1}^{S1}(r) + {}^E\boldsymbol{\omega}_r^{M1}(r) \cdot \boldsymbol{M}_{AeroB1}^{M1}(r) \right] dr + {}^E\boldsymbol{v}_r^{S1}(BldFlexL) \cdot \boldsymbol{F}_{TipDragB1}^{S1}(BldFlexL)
    
    这个公式是凯恩方程中广义主动力计算的典型示例。
    • \boldsymbol{F}_{AeroB1}^{S1}(r)\boldsymbol{M}_{AeroB1}^{M1}(r) 是实际的气动力和气动俯仰力矩。
    • {}^E\boldsymbol{v}_r^{S1}(r){}^E\boldsymbol{\omega}_r^{M1}(r) 分别是作用点处的偏速度偏角速度
    • 通过将实际气动力和气动扭矩投影到对应的偏速度和偏角速度方向上,直接计算出广义气动力,这正是凯恩方程中广义主动力 F_r 的定义。

总结

笔记 Blade 中的所有公式都完美契合凯恩方程的框架。它将复杂的叶片动力学问题分解为广义惯性力 (F_r^*) 和广义主动力 (F_r) 的计算,其中:

  • 广义惯性力被进一步分解为广义质量矩阵 [C(q,t)] 和速度相关的惯性力 ${-f(\dot{q},q,t)}_{B1}$。
  • 广义主动力则包含了弹性力、阻尼力、重力、气动力等各项贡献。

最终,将这些项组合起来,就可以得到叶片的运动方程,其形式为:

\mathbf{M}(q,t)\ddot{\mathbf{q}} + \mathbf{g}(\dot{\mathbf{q}},\mathbf{q},t) = \mathbf{Q}(\dot{\mathbf{q}},\mathbf{q},t)

其中,\mathbf{M}(q,t) 是广义质量矩阵,\mathbf{g}(\dot{\mathbf{q}},\mathbf{q},t) 包含了所有速度相关的惯性力,而 \mathbf{Q}(\dot{\mathbf{q}},\mathbf{q},t) 则是所有广义主动力(弹性、阻尼、重力、气动力)的总和。这种结构正是凯恩方程在柔性多体系统动力学建模中的典型应用。 [Timestamp: 2026/01/07 10:56:10]

user: BladeFillAugmat结合理论和代码,解释叶片部分是如何计算的 [Timestamp: 2026/01/07 11:08:54]

ai: 笔记 Blade 详细阐述了风力机叶片广义力(惯性力、弹性力、阻尼力、重力、气动力)的理论公式。而 FillAugMat 子程序(来自 FillAugmat 笔记)则是将这些理论公式转化为实际计算代码,用于构建系统的运动方程。

FillAugMat 的核心任务是填充一个增广矩阵 (Augmented Matrix) AugMat。这个矩阵通常用于表示系统的动力学方程:

\mathbf{M}(q,t)\ddot{\mathbf{q}} = \mathbf{F}(\dot{q},q,t)

其中:

  • \mathbf{M}(q,t) 是广义质量矩阵,它包含了与广义加速度 \ddot{\mathbf{q}} 相关的项。
  • \mathbf{F}(\dot{q},q,t) 是广义力向量,它包含了所有主动力(弹性力、阻尼力、重力、气动力)以及速度相关的惯性力(科里奥利力、离心力)。

FillAugMat 中,AugMat 的前 N 列(假设有 N 个自由度)构成了广义质量矩阵 $\mathbf{M}$,而最后一列(通过 p%NAug 索引)则存储了广义力向量 $\mathbf{F}$。

下面将结合 Blade 中的理论公式和 FillAugMat 中的代码,解释叶片部分的计算过程。

叶片部分的计算 (DO K = 1,p%NumBl 循环内)

FillAugMat 子程序首先会遍历所有叶片(DO K = 1,p%NumBl),对每个叶片计算其对系统运动方程的贡献。

1. 广义惯性力 (Generalized Inertia Forces)

凯恩方程中的广义惯性力 F_r^* 包含两部分:与广义加速度 \ddot{q} 相关的项(构成广义质量矩阵)和与广义速度 \dot{q} 相关的项(构成广义力向量的一部分)。

  • 理论依据: Blade 中的公式 (1), (4), (5), (6)。

    • 公式 (5) 定义了广义质量矩阵 [C(q,t)]_{B1} 的元素,它与 \ddot{q} 相关。
    • 公式 (6) 定义了速度相关的惯性力 ${-f(\dot{q},q,t)}_{B1}$,它与 \dot{q} 相关。
  • 代码实现:

    • 叶尖质量的贡献:
      AugMat(p%DOFs%PSBE(K,I),p%DOFs%PSBE(K,L)) = p%TipMass(K)*&
                                  DOT_PRODUCT( RtHSdat%PLinVelES(K, p%TipNode, p%DOFs%PSBE(K,I),0,:), &
                                               RtHSdat%PLinVelES(K, p%TipNode, p%DOFs%PSBE(K,L),0,:)    )
      
      这行代码计算了叶尖质量对广义质量矩阵的贡献。它对应于 Blade 公式 (5) 中的叶尖质量项 $m^{B1Tip} {}^{E}\boldsymbol{v}{\text{Row}}^{S1}(BldFlexL) \cdot {}^{E}\boldsymbol{v}{\text{Col}}^{S1}(BldFlexL)$。
      • p%TipMass(K) 是叶尖质量 $m^{B1Tip}$。
      • RtHSdat%PLinVelES(...) 是偏速度 ${}^{E}\boldsymbol{v}_{\text{Row}}^{S1}$。
    • 分布式叶片元素的贡献:
      AugMat(p%DOFs%PSBE(K,I),p%DOFs%PSBE(K,L)) = AugMat(...) + p%BElmntMass(J,K)*&
                                      DOT_PRODUCT( RtHSdat%PLinVelES(K,J,p%DOFs%PSBE(K,I),0,:), &
                                                   RtHSdat%PLinVelES(K,J,p%DOFs%PSBE(K,L),0,:)   )
      
      这行代码累加了每个叶片元素质量对广义质量矩阵的贡献。它对应于 Blade 公式 (5) 中的积分项 $\int_{0}^{BldFlexL} \mu^{B1}(r) , {}^{E}\boldsymbol{v}{\text{Row}}^{S1}(r) \cdot {}^{E}\boldsymbol{v}{\text{Col}}^{S1}(r) , dr$。
      • p%BElmntMass(J,K) 是叶片元素 J 的质量(对应 $\mu^{B1}(r) , dr$)。
      • RtHSdat%PLinVelES(...) 是偏速度 ${}^{E}\boldsymbol{v}_{\text{Row}}^{S1}(r)$。
    • 速度相关的惯性力 (科里奥利力、离心力):TmpVec1 的计算中,包含了 p%TipMass(K)*RtHSdat%LinAccESt(:,K,p%TipNode)p%BElmntMass(J,K)*RtHSdat%LinAccESt(:,K,J)。这里的 RtHSdat%LinAccESt 提供了叶片上点的绝对加速度,其中包含了速度相关的项。当这些项与偏速度进行点积并累加到 AugMat(..., p%NAug) 时,就形成了广义力向量中速度相关的惯性力部分,对应于 Blade 公式 (6)。

2. 广义弹性力 (Generalized Elastic Forces)

  • 理论依据: Blade 中的公式 (7), (8), (19)。

    • 弹性力是保守力,其广义力通过势能对广义坐标的负偏导数得到。
    • 公式 (8) 和 (19) 给出了具体的线性弹性力表达式,与广义位移 q 成正比。
  • 代码实现:

    IF ( p%DOF_Flag(DOF_BF(K,1)) )  THEN
       AugMat(    DOF_BF(K,1),p%NAug) = AugMat(DOF_BF(K,1),p%NAug)      &
                                      - p%KBF(K,1,1)*x%QT( DOF_BF(K,1)) &
                                      - p%KBF(K,1,2)*x%QT( DOF_BF(K,2)) &
                                      ...
    ENDIF
    

    这些代码块直接将弹性力项添加到广义力向量 AugMat(..., p%NAug) 中。

    • p%KBF(K,i,j)p%KBE(K,i,j) 是叶片 K 的广义刚度系数,对应于 Blade 公式 (8) 中的 {k'}_{ij}^{B1F} 和 ${k'}_{11}^{B1E}$。
    • x%QT(DOF) 是广义坐标 $q$。
    • 负号表示弹性力是恢复力。

3. 广义阻尼力 (Generalized Damping Forces)

  • 理论依据: Blade 中的公式 (13), (20)。

    • 阻尼力是非保守力,与广义速度 \dot{q} 成正比。
  • 代码实现:

    IF ( p%DOF_Flag(DOF_BF(K,1)) )  THEN
       AugMat(    DOF_BF(K,1),p%NAug) = AugMat(DOF_BF(K,1),p%NAug)      &
                                      ...
                                      - p%CBF(K,1,1)*x%QDT(DOF_BF(K,1)) &
                                      - p%CBF(K,1,2)*x%QDT(DOF_BF(K,2))
    ENDIF
    

    这些代码块直接将阻尼力项添加到广义力向量 AugMat(..., p%NAug) 中。

    • p%CBF(K,i,j)p%CBE(K,i,j) 是叶片 K 的广义阻尼系数。
    • x%QDT(DOF) 是广义速度 $\dot{q}$。
    • 负号表示阻尼力与速度方向相反。

4. 广义重力 (Generalized Gravity Forces)

  • 理论依据: Blade 中的公式 (21), (23)。

    • 重力是保守力,其广义力通过将重力投影到偏速度方向上得到。
  • 代码实现:

    • TmpVec1 的计算中,包含了重力项:
      TmpVec1 = RtHSdat%FSTipDrag(:,K) - p%TipMass(K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,p%TipNode) )
      ...
      TmpVec1 = RtHSdat%FSAero(:,K,J)*p%DRNodes(J) - p%BElmntMass(J,K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,J) )
      
      • p%Gravity*CoordSys%z2 代表重力加速度向量 $\boldsymbol{g}\boldsymbol{z}_2$。
      • p%TipMass(K)*( p%Gravity*CoordSys%z2 )p%BElmntMass(J,K)*( p%Gravity*CoordSys%z2 ) 分别是叶尖和叶片元素的重力。
    • 这些重力项随后通过点积 DOT_PRODUCT( RtHSdat%PLinVelES(...), TmpVec1 ) 被投影到偏速度方向上,并累加到 AugMat(..., p%NAug),对应于 Blade 公式 (23)。

5. 广义气动力 (Generalized Aerodynamic Forces)

  • 理论依据: Blade 中的公式 (24), (26)。

    • 气动力和气动扭矩是非保守力,其广义力通过将它们投影到偏速度和偏角速度方向上得到。
  • 代码实现:

    • TmpVec1TmpVec3 的计算中,包含了气动力和气动扭矩项:
      TmpVec1 = RtHSdat%FSTipDrag(:,K) - ... ! Tip drag
      ...
      TmpVec1 = RtHSdat%FSAero(:,K,J)*p%DRNodes(J) - ... ! Distributed aerodynamic force
      TmpVec3 = RtHSdat%MMAero(:,K,J)*p%DRNodes(J)       ! Distributed aerodynamic moment
      
          *   `RtHSdat%FSTipDrag(:,K)` 是叶尖阻力 $\boldsymbol{F}_{TipDragB1}^{S1}(BldFlexL)$。
      
      • RtHSdat%FSAero(:,K,J)*p%DRNodes(J) 是叶片元素 J 上的气动力 $\boldsymbol{F}_{AeroB1}^{S1}(r) , dr$。
      • RtHSdat%MMAero(:,K,J)*p%DRNodes(J) 是叶片元素 J 上的气动扭矩 $\boldsymbol{M}_{AeroB1}^{M1}(r) , dr$。
    • 这些力/扭矩随后通过点积 DOT_PRODUCT( RtHSdat%PLinVelES(...), TmpVec1 )DOT_PRODUCT( RtHSdat%PAngVelEM(...), TmpVec3 ) 被投影到偏速度和偏角速度方向上,并累加到 AugMat(..., p%NAug),对应于 Blade 公式 (26)。

总结

FillAugMat 子程序通过迭代叶片的各个部分(叶尖、分布式元素),并利用预先计算好的偏速度、偏角速度、绝对加速度以及各种力/力矩数据 (RtHSdat 结构体),系统地构建了风力机叶片部分的广义质量矩阵和广义力向量。它精确地将 Blade 中定义的理论公式(基于凯恩方程原理)转化为可计算的数值形式,从而为整个风力机系统的动力学仿真奠定基础。

值得注意的是,代码中还包含了对质量矩阵的对称性处理(先填充下三角,再镜像到上三角),以及其他系统组件(如塔架、传动链、偏航系统)的计算,但上述解释主要聚焦于叶片部分的实现。 [Timestamp: 2026/01/07 11:09:28]

user: BladeCalculateForcesMoments结合理论和代码,解释叶片部分是如何计算的 [Timestamp: 2026/01/07 14:04:15]

ai: CalculateForcesMoments 子程序在风力机动力学仿真中扮演着关键角色,它负责计算系统中各个部件(包括叶片)所受到的物理力和力矩。这些计算结果随后会被 FillAugMat 子程序(如前所述)用于构建系统的广义质量矩阵和广义力向量。

本解释将聚焦于 CalculateForcesMoments 中与叶片相关的计算部分,并将其与 Blade 笔记中的理论公式进行对照。

CalculateForcesMoments 子程序中的叶片部分计算

CalculateForcesMoments 子程序首先遍历所有叶片(DO K = 1,p%NumBl),然后对每个叶片上的各个节点/元素进行计算(DO J = 1,p%BldNodes)。

1. 气动力和气动扭矩的计算 (FSAero, MMAero, FSTipDrag)

这部分代码主要从外部气动模块(通过 u 输入)获取气动载荷,并将其转换为内部使用的格式。

  • 理论依据: Blade 中的公式 (24) 描述了广义气动力,其中包含了单位展向长度上的气动力 \boldsymbol{F}_{AeroB1}^{S1}(r) 和气动俯仰力矩 $\boldsymbol{M}{AeroB1}^{M1}(r)$,以及叶尖阻力 $\boldsymbol{F}{TipDragB1}^{S1}(BldFlexL)$。

  • 代码实现:

    • 叶尖阻力 (RtHSdat%FSTipDrag):
      RtHSdat%FSTipDrag = 0.0_ReKi         ! Calculate the tip drag forces if necessary
      !bjj: add this back when we've figured out how to handle the tip brakes:
      !RtHSdat%FSTipDrag(:,K) = m%CoordSys%m2(K,p%BldNodes,:)*SIGN( 0.5*p%AirDens*(RtHSdat%LinVelESm2(K)**2)*u%TBDrCon(K), -1.*RtHSdat%LinVelESm2(K) )
      
      目前代码中将叶尖阻力初始化为零,并注释掉了实际的计算逻辑。这表明在当前版本的实现中,叶尖阻力可能被简化或通过其他方式处理。如果启用,它将直接对应 Blade 公式 (24) 中的叶尖阻力项 $\boldsymbol{F}_{TipDragB1}^{S1}(BldFlexL)$。
    • 气动中心位置 (RtHSdat%rSAerCen):
      RtHSdat%rSAerCen(:,J,K) = p%rSAerCenn1(K,J)*CoordSys%n1(K,J,:) + p%rSAerCenn2(K,J)*CoordSys%n2(K,J,:)
      
      这行代码计算了叶片元素 J 上点 S 到其气动中心的位置向量 rSAerCen。这是计算气动俯仰力矩的关键,因为力矩通常是力与力臂的叉积。
    • 分布式气动力 (RtHSdat%FSAero) 和气动扭矩 (RtHSdat%MMAero):
      if (p%UseAD14) then
         RtHSdat%FSAero(:,K,J) = ( u%BladePtLoads(K)%Force(1,NodeNum) * CoordSys%te1(K,J,:) &
                                 + u%BladePtLoads(K)%Force(2,NodeNum) * CoordSys%te2(K,J,:) ) / p%DRNodes(J)
      
         RtHSdat%MMAero(:,K,J) = CROSS_PRODUCT( RtHSdat%rSAerCen(:,J,K), RtHSdat%FSAero(:,K,J) )&
                               + u%BladePtLoads(K)%Moment(3,NodeNum)/p%DRNodes(J) * CoordSys%te3(K,J,:)
      else
         ! ... (不同的坐标系转换和分量赋值)
      end if
      
      这部分代码从输入 u%BladePtLoads 中获取每个叶片元素的气动力和气动扭矩。
      • u%BladePtLoads(K)%Forceu%BladePtLoads(K)%Moment 是由外部气动模块(如 AeroDyn计算并提供的物理力/力矩。
      • p%DRNodes(J) 是叶片元素 J 的长度,用于将总力/力矩转换为单位展向长度上的力/力矩(对应 Blade 公式 (24) 中的 F_{AeroB1}^{S1}(r) 和 $M_{AeroB1}^{M1}(r)$)。
      • CROSS_PRODUCT( RtHSdat%rSAerCen(:,J,K), RtHSdat%FSAero(:,K,J) ) 计算了气动力在气动中心产生的力矩,这与 Blade 公式 (24) 中对 M_{AeroB1}^{M1}(r) 的描述一致,即可以包含由气动偏移引起的力矩。

2. 叶片根部偏力与偏力矩的计算 (PFrcS0B, PMomH0B)

这部分计算的是叶片根部(点 S(0))的偏力 (Partial Force)偏力矩 (Partial Moment)。这些“偏”量是惯性力对广义加速度的系数,用于构建广义质量矩阵。

  • 理论依据: Blade 中的公式 (1) 和 (4) 描述了广义惯性力,其中加速度项被分解为与 \ddot{q}_i 相关的部分(用于质量矩阵)和与 \dot{q}_i 相关的部分(用于广义力向量)。这里的偏力/偏力矩与广义质量矩阵的构建直接相关。

  • 代码实现:

    • 叶尖质量的贡献:
      TmpVec1 = -p%TipMass(K)*RtHSdat%PLinVelES(K,p%TipNode,p%DOFs%PSE(K,I),0,:)
      RtHSdat%PFrcS0B(:,K,p%DOFs%PSE(K,I)) = TmpVec1
      RtHSdat%PMomH0B(:,K,p%DOFs%PSE(K,I)) = CROSS_PRODUCT( RtHSdat%rS0S(:,K,p%TipNode), TmpVec1 )
      
      • p%TipMass(K) 是叶尖质量。
      • RtHSdat%PLinVelES(...) 是叶尖点 S(BldFlexL) 相对于广义坐标 q_I偏速度 ${}^{E}\boldsymbol{v}_{I}^{S1}(BldFlexL)$。
      • TmpVec1 实际上是叶尖质量乘以偏速度,这构成了广义质量矩阵的组成部分。负号表示惯性力的方向。
      • CROSS_PRODUCT( RtHSdat%rS0S(:,K,p%TipNode), TmpVec1 ) 将这个惯性力转换为关于叶片根部(点 S(0))的惯性力矩。RtHSdat%rS0S 是从叶片根部到叶尖的位置向量。
    • 分布式叶片元素的贡献:
      TmpVec1 = -p%BElmntMass(J,K)*RtHSdat%PLinVelES(K,J,p%DOFs%PSE(K,I),0,:)
      RtHSdat%PFrcS0B(:,K,p%DOFs%PSE(K,I)) = RtHSdat%PFrcS0B(:,K,p%DOFs%PSE(K,I)) + TmpVec1
      RtHSdat%PMomH0B(:,K,p%DOFs%PSE(K,I)) = RtHSdat%PMomH0B(:,K,p%DOFs%PSE(K,I)) + &
                                              CROSS_PRODUCT( RtHSdat%rS0S(:,K,J), TmpVec1 )
      
      这部分代码以类似的方式累加了每个叶片元素质量对叶片根部偏力/偏力矩的贡献。p%BElmntMass(J,K) 是叶片元素 J 的质量,RtHSdat%PLinVelES(...) 是叶片元素 J 处点 S1 相对于广义坐标 q_I 的偏速度 ${}^{E}\boldsymbol{v}_{I}^{S1}(r)$。

3. 叶片根部总力与总力矩的计算 (FrcS0Bt, MomH0Bt)

这部分计算的是叶片根部(点 S(0))的总力 (Total Force)总力矩 (Total Moment)。这些“总”量包含了所有主动力(气动力、重力)以及速度相关的惯性力(科里奥利力、离心力),它们共同构成了广义力向量。

  • 理论依据: Blade 中的公式 (6) 描述了速度相关的惯性力,公式 (23) 描述了广义重力,公式 (26) 描述了广义气动力。这些都是广义力向量的组成部分。

  • 代码实现:

    • 叶尖贡献:
      TmpVec1 = RtHSdat%FSTipDrag(:,K) - p%TipMass(K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,p%TipNode) )
      RtHSdat%FrcS0Bt(:,K) = TmpVec1
      RtHSdat%MomH0Bt(:,K) = CROSS_PRODUCT(  RtHSdat%rS0S(:,K,p%TipNode), TmpVec1 )
      
      • RtHSdat%FSTipDrag(:,K): 叶尖气动阻力。
      • p%TipMass(K)*p%Gravity*CoordSys%z2: 叶尖质量的重力。这对应于 Blade 公式 (21) 中的叶尖重力项。
      • p%TipMass(K)*RtHSdat%LinAccESt(:,K,p%TipNode): 叶尖质量乘以其绝对加速度。RtHSdat%LinAccESt 包含了科里奥利加速度和离心加速度等速度相关的项。当这些项被投影到偏速度方向时,就构成了 Blade 公式 (6) 中的速度相关惯性力。
      • CROSS_PRODUCT(...) 将这些力转换为关于叶片根部的力矩。
    • 分布式叶片元素贡献:
      TmpVec1 = RtHSdat%FSAero(:,K,J)*p%DRNodes(J) - p%BElmntMass(J,K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,J) )
      TmpVec2 = CROSS_PRODUCT( RtHSdat%rS0S(:,K,J), TmpVec1 )
      TmpVec3 = RtHSdat%MMAero(:,K,J)*p%DRNodes(J)
      
      RtHSdat%FrcS0Bt(:,K) = RtHSdat%FrcS0Bt(:,K) + TmpVec1
      RtHSdat%MomH0Bt(:,K) = RtHSdat%MomH0Bt(:,K) + TmpVec2 + TmpVec3
      
      • RtHSdat%FSAero(:,K,J)*p%DRNodes(J): 叶片元素 J 上的气动力。这对应于 Blade 公式 (24) 中的分布式气动力项。
      • p%BElmntMass(J,K)*p%Gravity*CoordSys%z2: 叶片元素 J 的重力。这对应于 Blade 公式 (21) 中的分布式重力项。
      • p%BElmntMass(J,K)*RtHSdat%LinAccESt(:,K,J): 叶片元素 J 质量乘以其绝对加速度。同样,这包含了速度相关的惯性力。
      • TmpVec3 = RtHSdat%MMAero(:,K,J)*p%DRNodes(J): 叶片元素 J 上的气动扭矩。这对应于 Blade 公式 (24) 中的分布式气动扭矩项。
      • CROSS_PRODUCT(...) 将力转换为关于叶片根部的力矩。

与广义力的联系

CalculateForcesMoments 子程序计算并存储在 RtHSdat 结构体中的这些物理力(FSAero, FSTipDrag, FrcS0Bt, PFrcS0B 等)和力矩(MMAero, MomH0Bt, PMomH0B 等)是构建系统动力学方程的中间结果

  • PFrcS0BPMomH0B (Partial Forces/Moments): 这些是与广义加速度 \ddot{q} 相关的系数,它们在 FillAugMat 中与偏速度/偏角速度进行点积,用于填充广义质量矩阵 $[C(q,t)]$。
  • FrcS0BtMomH0Bt (Total Forces/Moments): 这些是包含了所有主动力(气动力、重力、弹性力、阻尼力)以及速度相关的惯性力(科里奥利力、离心力)的总和。它们在 FillAugMat 中与偏速度/偏角速度进行点积,用于填充广义力向量 ${-f(\dot{q},q,t)}$。

简而言之,CalculateForcesMoments 负责将外部输入(如气动载荷)和系统内部状态(如位置、速度、加速度)转化为作用在叶片上的具体物理力和力矩,并进一步分解为“偏”量和“总”量,为后续在 FillAugMat 中构建完整的广义动力学方程做准备。它将 Blade 笔记中描述的各种力(惯性、重力、气动)的物理表达式,通过具体的数值计算和向量运算实现出来。 [Timestamp: 2026/01/07 14:08:00]

user: BladeCalculateAngularPosVelPAcc结合理论和代码,解释叶片部分是如何计算的 [Timestamp: 2026/01/07 14:23:01]

ai: CalculateAngularPosVelPAcc 子程序是风力机动力学模型中一个非常基础且关键的模块,它负责计算系统中各个刚体和柔性体元素的角位置、角速度、偏角速度及其一阶导数(用于角加速度)。这些运动学量是构建广义惯性力(特别是科里奥利力和离心力项)以及将物理力/力矩投影到广义坐标系中的基础。

本解释将聚焦于 CalculateAngularPosVelPAcc 中与叶片相关的计算部分,并将其与 Blade 笔记中的理论公式进行对照。

凯恩方程中的运动学基础

在凯恩方程中,任何点的速度 \boldsymbol{v} 和任何刚体的角速度 \boldsymbol{\omega} 都可以表示为广义速度 \dot{q}_i 的线性组合:

\boldsymbol{v} = \sum_i \boldsymbol{v}_i \dot{q}_i + \boldsymbol{v}_t \boldsymbol{\omega} = \sum_i \boldsymbol{\omega}_i \dot{q}_i + \boldsymbol{\omega}_t

其中:

  • \boldsymbol{v}_i\boldsymbol{\omega}_i 分别是相对于广义速度 \dot{q}_i偏速度 (Partial Velocity)偏角速度 (Partial Angular Velocity)
  • \boldsymbol{v}_t\boldsymbol{\omega}_t 是与广义速度无关的项(通常是由于参考系运动或时间显式依赖)。

加速度 \boldsymbol{a} 和角加速度 \boldsymbol{\alpha} 则涉及偏速度/偏角速度对时间的导数:

\boldsymbol{a} = \sum_i \boldsymbol{v}_i \ddot{q}_i + \sum_i \frac{d\boldsymbol{v}_i}{dt} \dot{q}_i + \frac{d\boldsymbol{v}_t}{dt} \boldsymbol{\alpha} = \sum_i \boldsymbol{\omega}_i \ddot{q}_i + \sum_i \frac{d\boldsymbol{\omega}_i}{dt} \dot{q}_i + \frac{d\boldsymbol{\omega}_t}{dt}

其中,\frac{d\boldsymbol{v}_i}{dt}\frac{d\boldsymbol{\omega}_i}{dt} 是偏速度/偏角速度的一阶导数,它们在惯性力中产生了科里奥利力和离心力项。

CalculateAngularPosVelPAcc 子程序正是计算这些偏速度、偏角速度及其导数,以及总角速度和总角加速度中与 \ddot{q} 无关的部分。

CalculateAngularPosVelPAcc 子程序中的叶片部分计算

该子程序首先计算了从平台到轮毂的各个刚体的角运动学量,然后进入叶片循环 (DO K = 1,p%NumBl) 来计算叶片的柔性运动。

1. 轮毂的角运动学量 (RtHSdat%AngVelEH, RtHSdat%PAngVelEH, RtHSdat%AngAccEHt)

在计算叶片运动之前需要先确定叶片根部所连接的轮毂Hub体 H在惯性系 E 中的角运动学量。

  • RtHSdat%PAngVelEH(:,0,:) (轮毂的偏角速度):
    RtHSdat%PAngVelEH(       :,0,:)= RtHSdat%PAngVelEL(:,0,:)
    RtHSdat%AngVelEH               = RtHSdat%AngVelEL
    IF ( p%NumBl == 2 )  THEN ! 2-blader
       RtHSdat%PAngVelEH(DOF_Teet,0,:)= CoordSys%f2
       RtHSdat%AngVelEH               = RtHSdat%AngVelEH + x%QDT(DOF_Teet)*RtHSdat%PAngVelEH(DOF_Teet,0,:)
    ENDIF
    
    这部分代码计算了轮毂相对于惯性系 E 的偏角速度。它基于低速轴 (LSS体 L) 的偏角速度 RtHSdat%PAngVelEL,并考虑了可能的摆振 (Teeter) 自由度(如果存在)。CoordSys%f2 是摆振轴的单位向量。
  • RtHSdat%AngVelEH (轮毂的总角速度): 通过将轮毂的偏角速度与对应的广义速度 x%QDT(DOF) 相乘并求和,得到轮毂在惯性系 E 中的总角速度。
  • RtHSdat%PAngVelEH(:,1,:) (轮毂偏角速度的一阶导数):
    RtHSdat%PAngVelEH(       :,1,:) = RtHSdat%PAngVelEL(:,1,:)
    IF ( p%NumBl == 2 )  THEN ! 2-blader
       RtHSdat%PAngVelEH(DOF_Teet,1,:) = CROSS_PRODUCT(  RtHSdat%AngVelEH,                    RtHSdat%PAngVelEH(DOF_Teet,0,:) )
       ...
    ENDIF
    ```    这部分计算了轮毂偏角速度的一阶导数。对于旋转的参考系,偏角速度的导数通常涉及当前角速度与偏角速度的叉积(例如,科里奥利效应)。
    
  • RtHSdat%AngAccEHt (轮毂角加速度中与 \ddot{q} 无关的部分):
    RtHSdat%AngAccEHt               =                  AngAccELt
    IF ( p%NumBl == 2 )  THEN ! 2-blader
       ...
       RtHSdat%AngAccEHt               =                 RtHSdat%AngAccEHt   + x%QDT(DOF_Teet)*RtHSdat%PAngVelEH(DOF_Teet,1,:)
    ENDIF
    
    这部分计算了轮毂在惯性系 E 中的角加速度中与广义加速度 \ddot{q} 无关的项。它包含了由于广义速度 \dot{q} 引起的科里奥利和离心效应。

2. 叶片柔性点的角运动学量 (RtHSdat%PAngVelEM, RtHSdat%AngVelEM, RtHSdat%AngAccEKt)

接下来,子程序遍历每个叶片(K)上的每个节点/元素(J),计算这些柔性点的角运动学量。

  • 理论依据: Blade 中的公式 (4) 描述了叶片上点 S1 的绝对加速度,其中包含了与偏速度一阶导数相关的项。这些偏速度一阶导数正是由角运动学量(特别是偏角速度的导数)推导而来。公式 (24) 中的广义气动力也需要叶片元素的偏角速度 $\boldsymbol{\omega}_r^{M1}(r)$。

  • 代码实现:

    • 叶片元素偏角速度 (RtHSdat%PAngVelEM(K,J,:,0,:)):
      RtHSdat%PAngVelEM(K,J,          :,0,:) = RtHSdat%PAngVelEH(:,0,:)
      RtHSdat%PAngVelEM(K,J,DOF_BF(K,1),0,:) = - p%TwistedSF(K,2,1,J,1)*CoordSys%j1(K,:) &
                                               + p%TwistedSF(K,1,1,J,1)*CoordSys%j2(K,:)
      RtHSdat%PAngVelEM(K,J,DOF_BF(K,2),0,:) = - p%TwistedSF(K,2,2,J,1)*CoordSys%j1(K,:) &
                                               + p%TwistedSF(K,1,2,J,1)*CoordSys%j2(K,:)
      RtHSdat%PAngVelEM(K,J,DOF_BE(K,1),0,:) = - p%TwistedSF(K,2,3,J,1)*CoordSys%j1(K,:) &
                                               + p%TwistedSF(K,1,3,J,1)*CoordSys%j2(K,:)
      
      这部分代码计算了叶片元素 J 相对于惯性系 E 的偏角速度。它首先继承了轮毂的偏角速度 RtHSdat%PAngVelEH,然后添加了由叶片柔性模态(挥舞 DOF_BF 和摆振 DOF_BE)引起的额外偏角速度。
      • p%TwistedSF扭转形状函数 (Twisted Shape Function),它描述了叶片在柔性变形时,其横截面的扭转和弯曲如何影响局部坐标系的方向。这些形状函数与 CoordSys%j1(K,:)CoordSys%j2(K,:)(叶片局部坐标系的单位向量)结合,定义了柔性模态引起的偏角速度分量。
      • 这些偏角速度 RtHSdat%PAngVelEM 直接对应于 Blade 公式 (24) 中的 ${}^E\boldsymbol{\omega}_r^{M1}(r)$。
    • 叶片元素总角速度 (RtHSdat%AngVelEM):
      AngVelHM  =     x%QDT(DOF_BF(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,1),0,:) &
                    + x%QDT(DOF_BF(K,2))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,2),0,:) &
                    + x%QDT(DOF_BE(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BE(K,1),0,:)
      RtHSdat%AngVelEM(:,J,K              ) =  RtHSdat%AngVelEH + AngVelHM
      
      叶片元素的总角速度是轮毂的总角速度 RtHSdat%AngVelEH 加上由叶片柔性模态引起的相对角速度 AngVelHM
    • 叶片元素偏角速度的一阶导数 (RtHSdat%PAngVelEM(K,J,:,1,:)): 代码中这部分被注释掉了:
      !      RtHSdat%PAngVelEM(K,J,          :,1,:) = RtHSdat%PAngVelEH(:,1,:)
      !      RtHSdat%PAngVelEM(K,J,DOF_BF(K,1),1,:) = CROSS_PRODUCT(   RtHSdat%AngVelEH, PAngVelEM(K,J,DOF_BF(K,1),0,:) )
      !      RtHSdat%PAngVelEM(K,J,DOF_BF(K,2),1,:) = CROSS_PRODUCT(   RtHSdat%AngVelEH, PAngVelEM(K,J,DOF_BF(K,2),0,:) )
      !      RtHSdat%PAngVelEM(K,J,DOF_BE(K,1),1,:) = CROSS_PRODUCT(   RtHSdat%AngVelEH, PAngVelEM(K,J,DOF_BE(K,1),0,:) )
      
      注释说明这些计算目前未被使用。如果需要考虑叶片元素的惯性力矩(例如,当叶片元素具有显著的转动惯量时),则需要计算这些偏角速度的一阶导数。这些导数在凯恩方程中用于计算角加速度中与广义速度相关的项。
  • RtHSdat%AngAccEKt (叶片元素角加速度中与 \ddot{q} 无关的部分):

    RtHSdat%AngAccEKt(:,J              ,K) =  RtHSdat%AngAccEHt + x%QDT(DOF_BF(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,1),1,:) &
                                                                 + x%QDT(DOF_BF(K,2))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,2),1,:) &
                                                                 + x%QDT(DOF_BE(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BE(K,1),1,:)
    

    这部分计算了叶片元素在惯性系 E 中的角加速度中与广义加速度 \ddot{q} 无关的项。它结合了轮毂的相应项 RtHSdat%AngAccEHt 和由叶片柔性模态引起的、与广义速度 x%QDT(DOF) 及其偏角速度一阶导数 RtHSdat%PAngVelEM(K,J,DOF,1,:) 相关的项。这些项在 Blade 公式 (4) 中,当计算绝对加速度时,会通过叉积运算产生科里奥利和离心加速度。

总结

CalculateAngularPosVelPAcc 子程序是整个风力机动力学模型中运动学计算的基石。它通过层层递进的方式,从基础的平台运动开始,逐步计算出轮毂以及每个叶片柔性点的角位置、角速度、偏角速度及其一阶导数。

这些计算结果对于以下方面至关重要:

  1. 广义惯性力的计算: Blade 公式 (4) 和 (6) 中的速度相关惯性力项(科里奥利力和离心力)需要偏速度和偏角速度的一阶导数。
  2. 广义气动力的计算: Blade 公式 (24) 中的气动扭矩项需要叶片元素的偏角速度。
  3. 坐标系转换: 准确的角位置和角速度是进行各种力(如气动力、重力)在不同坐标系之间转换的基础。

通过这些详细的运动学计算,CalculateAngularPosVelPAcc 为后续的力和力矩计算(如 CalculateForcesMoments)和最终的运动方程构建(如 FillAugMat)提供了所有必要的运动学输入。 [Timestamp: 2026/01/07 14:23:28]

user: BladeCalculatePositions结合理论和代码,解释代码的作用 [Timestamp: 2026/01/07 14:29:33]

ai: CalculatePositions 子程序在风力机动力学模型中负责计算系统中各个关键点和分布式元素(包括叶片)的位置向量。这些位置信息是进行运动学分析、计算力臂、以及最终构建广义力方程的基础。

本解释将聚焦于 CalculatePositions 中与叶片相关的计算部分,并将其与 Blade 笔记中的理论公式进行对照。

凯恩方程中的位置学基础

在凯恩方程中,系统的构型由广义坐标 q_i 描述。系统中任意一点的绝对位置向量 \boldsymbol{r} 可以表示为广义坐标的函数:

\boldsymbol{r} = \boldsymbol{r}(q_1, q_2, \ldots, q_n, t)

这些位置向量是计算偏速度、偏角速度以及后续的力和力矩(特别是力矩的力臂)的基础。

CalculatePositions 子程序中的叶片部分计算

CalculatePositions 子程序首先计算了从平台到轮毂的各个刚体之间的位置向量,然后进入叶片循环 (DO K = 1,p%NumBl) 来计算叶片柔性点的位移。

1. 叶片根部到叶片柔性点的相对位置 (RtHSdat%rS0S)

这部分代码计算了从叶片根部(点 S(0))到叶片上任意柔性点(点 S(r))的相对位置向量。这个相对位置包含了叶片的柔性变形。

  • 理论依据: 叶片的柔性变形通常通过模态叠加法来描述。叶片上任意一点的位移可以表示为各阶模态形状函数与对应广义坐标的乘积之和。虽然 Blade 笔记中没有直接给出位置向量的公式,但广义弹性力 (公式 7, 8) 和广义质量 (公式 16, 17) 都依赖于模态形状函数 $\phi(r)$,这些形状函数正是描述叶片柔性变形的基础。

  • 代码实现:

    • 叶尖位置 (RtHSdat%rS0S(:,K,p%TipNode)):
      RtHSdat%rS0S(:,K,p%TipNode) = ( p%TwistedSF(K,1,1,p%TipNode,0)*x%QT( DOF_BF(K,1) ) &
                                    + p%TwistedSF(K,1,2,p%TipNode,0)*x%QT( DOF_BF(K,2) ) &
                                    + p%TwistedSF(K,1,3,p%TipNode,0)*x%QT( DOF_BE(K,1) )                     )*CoordSys%j1(K,:) &
                                  + ( p%TwistedSF(K,2,1,p%TipNode,0)*x%QT( DOF_BF(K,1) ) &
                                    + p%TwistedSF(K,2,2,p%TipNode,0)*x%QT( DOF_BF(K,2) ) &
                                    + p%TwistedSF(K,2,3,p%TipNode,0)*x%QT( DOF_BE(K,1) )                     )*CoordSys%j2(K,:) &
                                  + ( p%BldFlexL - 0.5* &
                                  (      p%AxRedBld(K,1,1,p%TipNode)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BF(K,1) ) &
                                    +    p%AxRedBld(K,2,2,p%TipNode)*x%QT( DOF_BF(K,2) )*x%QT( DOF_BF(K,2) ) &
                                    +    p%AxRedBld(K,3,3,p%TipNode)*x%QT( DOF_BE(K,1) )*x%QT( DOF_BE(K,1) ) &
                                    + 2.*p%AxRedBld(K,1,2,p%TipNode)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BF(K,2) ) &
                                    + 2.*p%AxRedBld(K,2,3,p%TipNode)*x%QT( DOF_BF(K,2) )*x%QT( DOF_BE(K,1) ) &
                                    + 2.*p%AxRedBld(K,1,3,p%TipNode)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BE(K,1) ) ) )*CoordSys%j3(K,:)
      
      这行代码计算了从叶片根部到叶尖的相对位置向量 rS0S
      • p%TwistedSF(K,i,j,Node,0): 这是扭转形状函数 (Twisted Shape Function),它描述了叶片在柔性变形时,其在叶片局部坐标系 j1, j2 方向上的位移。x%QT(DOF_BF(K,1)) 等是对应的广义坐标(模态幅值)。
      • CoordSys%j1(K,:), CoordSys%j2(K,:), CoordSys%j3(K,:): 叶片 K 的局部坐标系单位向量。
      • p%BldFlexL: 叶片柔性段的长度。
      • p%AxRedBld(K,i,j,Node): 轴向缩短系数 (Axial Shortening Coefficient)。由于叶片的弯曲变形会导致其轴向长度的微小缩短(二阶效应),这些系数用于修正沿叶片轴向 j3 方向的位移。这是一个非线性项,与广义坐标的平方项相关。
      • 物理意义: 整个表达式通过模态叠加和轴向缩短效应,精确地描述了叶片在柔性变形下的三维位移。
    • 分布式叶片元素位置 (RtHSdat%rS0S(:,K,J)):DO J = 1,p%BldNodes 循环中,以类似的方式计算了从叶片根部到每个叶片元素 J 的相对位置向量。

2. 轮毂旋转中心到叶片柔性点的相对位置 (RtHSdat%rQS)

这部分计算了从轮毂旋转中心(点 Q到叶片上任意柔性点点 S(r))的相对位置向量。

  • 代码实现:
    RtHSdat%rQS (:,K,p%TipNode) = RtHSdat%rS0S(:,K,p%TipNode) + p%HubRad*CoordSys%j3(K,:)
    
    这行代码将叶片根部到叶尖的相对位置 rS0S 加上从轮毂旋转中心到叶片根部的径向距离 p%HubRad*CoordSys%j3(K,:),从而得到从轮毂旋转中心到叶尖的相对位置 rQS
    • p%HubRad: 轮毂半径,即从轮毂旋转中心到叶片根部的径向距离。

3. 惯性系原点到叶片柔性点的绝对位置 (RtHSdat%rS)

这部分计算了从惯性系原点(通常是地面)到叶片上任意柔性点(点 S(r))的绝对位置向量。

  • 代码实现:
    RtHSdat%rS  (:,K,p%TipNode) = RtHSdat%rQS (:,K,p%TipNode) + RtHSdat%rQ
    
    这行代码将从轮毂旋转中心到叶尖的相对位置 rQS 加上从惯性系原点到轮毂旋转中心的绝对位置 RtHSdat%rQ,从而得到从惯性系原点到叶尖的绝对位置 rS
    • RtHSdat%rQ: 这是在叶片循环之前计算的,表示从惯性系原点到轮毂旋转中心(点 Q的绝对位置向量。

4. 其他关键位置向量

除了叶片柔性点的位置,子程序还计算了其他与叶片相关的关键位置向量:

  • RtHSdat%rPS0(:,K) (从摆振销到叶片根部的位置):
    RtHSdat%rPS0(:,K) = RtHSdat%rPQ + p%HubRad*CoordSys%j3(K,:)
    
    这表示从摆振销Teeter Pin点 P到叶片根部点 S(0))的位置向量。RtHSdat%rPQ 是从摆振销到轮毂旋转中心的位置向量。这个向量在计算叶片根部力矩时非常重要。

总结

CalculatePositions 子程序通过以下步骤,为叶片部分的动力学分析提供了全面的位置信息:

  1. 定义基准位置: 首先计算了风力机各个主要刚体(平台、塔架、机舱、轮毂)之间的相对和绝对位置向量。
  2. 处理叶片柔性: 针对每个叶片,利用扭转形状函数轴向缩短系数,结合广义坐标 x%QT,精确地计算了叶片上每个柔性点相对于叶片根部、轮毂旋转中心以及惯性系原点的三维位置。
  3. 提供力臂信息: 这些位置向量是计算力矩的关键力臂。例如,在 CalculateForcesMoments 中计算叶片根部力矩时,就需要用到 RtHSdat%rS0SRtHSdat%rPS0 等作为力臂。
  4. 支持运动学计算: 准确的位置信息是计算速度和加速度(包括偏速度和偏角速度)的基础,这些运动学量在 CalculateAngularPosVelPAccCalculateLinearVelPAcc 中被进一步计算。

通过这些详细的位置计算,CalculatePositions 确保了风力机叶片在复杂三维运动和柔性变形下的几何构型被准确地捕捉,为后续的动力学方程构建提供了坚实的基础。 [Timestamp: 2026/01/07 14:29:57]

user: BladeCoeff结合理论和代码,解释叶片部分是如何计算的 [Timestamp: 2026/01/07 16:47:41]

ai: Coeff 子程序在风力机动力学仿真中扮演着初始化和预计算关键参数的角色。它在仿真开始时被调用,根据用户输入的几何、质量、刚度、阻尼等数据,计算出各种系数,这些系数随后在整个仿真过程中被其他子程序(如 CalculatePositions, CalculateAngularPosVelPAcc, CalculateForcesMoments, FillAugMat 等)使用。

本解释将聚焦于 Coeff 中与叶片相关的计算部分,并将其与 Blade 笔记中的理论公式进行对照。

Coeff 子程序中的叶片部分计算

Coeff 子程序中与叶片相关的计算主要集中在几个方面:气动中心位置、叶片质量属性、广义质量、广义刚度、固有频率、广义阻尼以及扭转形状函数和轴向缩短系数的预计算。

1. 气动中心位置 (p%rSAerCenn1, p%rSAerCenn2)

  • 理论依据: Blade 公式 (24) 中提到气动俯仰力矩 M_{AeroB1}^{M1}(r) 可以包含由气动偏移引起的力矩。这意味着需要知道气动力作用点(气动中心)相对于叶片参考点的位置。

  • 代码作用:

    DO K = 1,p%NumBl          ! Loop through the blades
       DO J = 1,p%BldNodes    ! Loop through the blade nodes / elements
          TmpDist           = ( 0.25 - p%PitchAxis(K,J) )*p%Chord(J)   ! Distance along the chordline from point S (25% chord) to the aerodynamic center of the blade element J--positive towards the trailing edge.
          TmpDistj1         = TmpDist*p%SAeroTwst(J)                   ! Distance along the j1-axis   from point S (25% chord) to the aerodynamic center of the blade element J
          TmpDistj2         = TmpDist*p%CAeroTwst(J)                   ! Distance along the j2-axis   from point S (25% chord) to the aerodynamic center of the blade element J
          p%rSAerCenn1(K,J) = TmpDistj1*p%CThetaS(K,J) - TmpDistj2*p%SThetaS(K,J)
          p%rSAerCenn2(K,J) = TmpDistj1*p%SThetaS(K,J) + TmpDistj2*p%CThetaS(K,J)
       ENDDO
    ENDDO
    

    这部分代码计算了每个叶片元素的气动中心相对于叶片参考点 S通常是 25% 弦长处)在叶片局部坐标系 n1n2 方向上的分量 p%rSAerCenn1p%rSAerCenn2

    • p%PitchAxis(K,J): 叶片 K 元素 J 的桨距轴位置(相对于弦长)。
    • p%Chord(J): 叶片元素 J 的弦长。
    • TmpDist: 气动中心与参考点 S 沿弦长的距离。
    • p%SAeroTwst(J), p%CAeroTwst(J): 气动扭转的正弦和余弦值,用于将沿弦长的距离分解到叶片局部 j1j2 轴。
    • p%CThetaS(K,J), p%SThetaS(K,J): 叶片局部坐标系与气动坐标系之间的转换因子。
    • 作用: 这些预计算的距离在 CalculateForcesMoments 子程序中用于计算气动俯仰力矩的力臂。

2. 叶片质量属性 (p%BldMass, p%FirstMom, p%SecondMom, p%BldCG)

  • 理论依据: Blade 公式 (2) 和 (3) 定义了叶片分布式质量 \mu^{B1}(r) 和叶尖质量 $m^{B1Tip}$。这些是计算叶片总质量、质心和转动惯量的基础。

  • 代码作用:

    p%BldMass  (K) = p%TipMass(K)
    p%FirstMom (K) = p%TipMass(K)*p%BldFlexL
    p%SecondMom(K) = p%TipMass(K)*p%BldFlexL*p%BldFlexL
    ...
    p%BElmntMass(J,K) = p%MassB(K,J)*p%DRNodes(J)
    ...
    p%BldMass  (K) = p%BldMass  (K) + p%BElmntMass(J,K)
    p%FirstMom (K) = p%FirstMom (K) + p%BElmntMass(J,K)*p%RNodes(J)
    p%SecondMom(K) = p%SecondMom(K) + p%BElmntMass(J,K)*p%RNodes(J)*p%RNodes(J)
    ...
    p%BldCG    (K) = p%FirstMom (K) / p%BldMass    (K)
    

    这部分代码通过对叶片元素质量和叶尖质量进行积分(或求和),计算了每个叶片的总质量 p%BldMass、一阶质量矩 p%FirstMom、二阶质量矩 p%SecondMom 以及质心位置 p%BldCG

    • p%MassB(K,J): 叶片 K 元素 J 的单位长度质量。
    • p%DRNodes(J): 叶片元素 J 的长度。
    • p%RNodes(J): 叶片元素 J 的径向位置。
    • 作用: 这些质量属性是计算广义惯性力、广义重力以及整个风力机系统总质量和质心的基础。

3. 广义质量 (MBF, MBE)

  • 理论依据: Blade 公式 (16) 和 (17) 定义了广义质量 m_{ij}^{\prime B1F} 和 $m_{11}^{\prime B1E}$,它们通过对叶片分布式质量和模态形状函数进行积分得到。

  • 代码作用:

    MBF(K,1,1) = p%TipMass(K)
    MBF(K,2,2) = p%TipMass(K)
    MBE(K,1,1) = p%TipMass(K)
    ...
    Shape1 = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl1Sh(:,K), 0, ErrStat, ErrMsg )
    Shape2 = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl2Sh(:,K), 0, ErrStat, ErrMsg )
    MBF    (K,1,1) = MBF    (K,1,1) + p%BElmntMass(J,K)*Shape1*Shape1
    MBF    (K,2,2) = MBF    (K,2,2) + p%BElmntMass(J,K)*Shape2*Shape2
    Shape  = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldEdgSh(:,K), 0, ErrStat, ErrMsg )
    MBE    (K,1,1) = MBE    (K,1,1) + p%BElmntMass(J,K)*Shape *Shape
    

    这部分代码计算了叶片挥舞方向 (MBF) 和摆振方向 (MBE) 的广义质量。

    • SHP(..., 0, ...): 这是一个函数,用于获取模态形状函数 \phi(r) 的零阶导数(即形状函数本身)。
    • p%BldFl1Sh(:,K), p%BldFl2Sh(:,K), p%BldEdgSh(:,K): 分别是叶片 K 的第一阶挥舞模态、第二阶挥舞模态和第一阶摆振模态的形状函数数据。
    • 作用: 这些广义质量是计算叶片固有频率 (公式 14, 15) 和广义惯性力 (公式 5) 的关键参数。

4. 广义刚度 (p%KBF, p%KBE, KBFCent, KBECent)

  • 理论依据: Blade 公式 (9) 和 (11) 定义了未考虑离心刚化效应时的广义刚度 {k'}_{ij}^{B1F} 和 ${k'}_{11}^{B1E}$。代码中还计算了离心刚化效应引起的刚度项。

  • 代码作用:

    ElmntStff      = p%StiffBF(K,J)*p%DRNodes(J)
    Shape1 = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl1Sh(:,K), 2, ErrStat, ErrMsg )
    Shape2 = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl2Sh(:,K), 2, ErrStat, ErrMsg )
    p%KBF    (K,1,1) = p%KBF    (K,1,1) + ElmntStff*Shape1*Shape1
    p%KBF    (K,1,2) = p%KBF    (K,1,2) + ElmntStff*Shape1*Shape2
    p%KBF    (K,2,1) = p%KBF    (K,2,1) + ElmntStff*Shape2*Shape1
    p%KBF    (K,2,2) = p%KBF    (K,2,2) + ElmntStff*Shape2*Shape2
    ...
    ElmntStff      = FMomAbvNd(K,J)*p%DRNodes(J)*p%RotSpeed**2
    Shape1 = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl1Sh(:,K), 1, ErrStat, ErrMsg )
    KBFCent(K,1,1) = KBFCent(K,1,1) + ElmntStff*Shape1*Shape1
    

    这部分代码计算了叶片挥舞方向 (p%KBF) 和摆振方向 (p%KBE) 的广义刚度,包括结构刚度项和离心刚化项 (KBFCent, KBECent)。

    • SHP(..., 2, ...): 获取模态形状函数的二阶导数(曲率),对应于 Blade 公式 (9) 和 (11) 中的 $\frac{d^2 \phi}{dr^2}$。
    • p%StiffBF(K,J): 叶片 K 元素 J 的挥舞刚度 $EI^{B1F}(r)$。
    • FMomAbvNd(K,J)*p%DRNodes(J)*p%RotSpeed**2: 离心刚化效应项,与叶片上方质量的一阶矩和转速平方相关。
    • SHP(..., 1, ...): 获取模态形状函数的一阶导数,用于离心刚化项。
    • 作用: 这些广义刚度是计算广义弹性力 (公式 8, 19) 和固有频率 (公式 14, 15) 的关键参数。

5. 固有频率 (p%FreqBF, p%FreqBE)

  • 理论依据: Blade 公式 (14) 和 (15) 定义了未考虑离心刚化效应时的固有频率 f_i^{\prime B1F} 和 $f_i^{\prime B1E}$。

  • 代码作用:

    p%FreqBF(K,I,1) = Inv2Pi*SQRT(   p%KBF(K,I,I)                   /( MBF(K,I,I) - p%TipMass(K) ) )
    p%FreqBF(K,I,2) = Inv2Pi*SQRT(   p%KBF(K,I,I)                   /  MBF(K,I,I)                )
    p%FreqBF(K,I,3) = Inv2Pi*SQRT( ( p%KBF(K,I,I) + KBFCent(K,I,I) )/  MBF(K,I,I)                )
    

    这部分代码计算了叶片在不同条件下(是否考虑叶尖质量、是否考虑离心刚化)的固有频率。

    • Inv2Pi: $1/(2\pi)$。
    • 作用: 这些固有频率是计算广义阻尼力 (公式 13, 20) 的关键参数。

6. 广义阻尼 (p%CBF, p%CBE)

  • 理论依据: Blade 公式 (13) 定义了广义阻尼力,其中阻尼系数与结构阻尼比 $\zeta$、广义刚度 k' 和固有频率 f' 相关。

  • 代码作用:

    p%CBF(K,I,L) = ( 0.01*p%BldFDamp(K,L) )*p%KBF(K,I,L)/( Pi*p%FreqBF(K,L,1) )
    p%CBE      (K,1,1) = ( 0.01*p%BldEDamp(K,1) )*p%KBE(K,1,1)/( Pi*p%FreqBE(K,1,1) )
    

    这部分代码根据瑞利阻尼假设,计算了叶片挥舞方向 (p%CBF) 和摆振方向 (p%CBE) 的广义阻尼系数。

    • p%BldFDamp(K,L): 叶片 K 的挥舞阻尼比 $\zeta$。
    • Pi: $\pi$。
    • 作用: 这些广义阻尼系数是计算广义阻尼力 (公式 13, 20) 的关键参数。

7. 扭转形状函数和轴向缩短系数 (p%TwistedSF, p%AxRedBld)

  • 理论依据: 这些系数直接用于 CalculatePositions 子程序中计算叶片柔性点的位移,如前所述。它们描述了叶片柔性变形的几何特性。

  • 代码作用:

    ! Calculate the 2nd derivatives of the twisted shape functions:
    Shape  = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl1Sh(:,K), 2, ErrStat, ErrMsg )
    p%TwistedSF(K,1,1,J,2) =  Shape*p%CThetaS(K,J)
    ...
    ! Integrate to find the 1st derivatives of the twisted shape functions:
    TwstdSF     (  I,L,  1) = p%TwistedSF(K,I,L,J,2)*0.5*p%DRNodes(J)
    p%TwistedSF   (K,I,L,J,1) = TwstdSF   ( I,L,  1)
    ...
    ! Integrate to find the twisted shape functions themselves (i.e., their zeroeth derivative):
    TwstdSF     (  I,L,  0) = p%TwistedSF(K,I,L,J,1)*0.5*p%DRNodes(J)
    p%TwistedSF   (K,I,L,J,0) = TwstdSF   ( I,L,  0)
    ...
    ! Integrate to find the blade axial reduction shape functions:
    AxRdBld    (  I,L  ) = 0.5*p%DRNodes(J)*(                          &
                         p%TwistedSF(K,1,I,L,1)*p%TwistedSF(K,1,L,J,1) &
                       + p%TwistedSF(K,2,I,L,1)*p%TwistedSF(K,2,L,J,1) )
    p%AxRedBld   (K,I,L,J) = AxRdBld(I,L)
    

    这部分代码通过对模态形状函数进行积分和组合,预计算了叶片上每个节点/元素在不同阶导数下的扭转形状函数 p%TwistedSF轴向缩短系数 p%AxRedBld

    • SHP 函数用于获取模态形状函数及其导数。
    • p%CThetaS, p%SThetaS: 叶片局部坐标系与气动坐标系之间的转换因子。
    • 作用: 这些系数在 CalculatePositions 中用于计算叶片柔性点的精确位置,包括弯曲和扭转引起的位移以及轴向缩短效应。

总结

Coeff 子程序是风力机动力学模型中的“大脑”,它在仿真开始前,根据用户提供的原始输入数据,执行大量的预计算和集成操作。对于叶片部分,它:

  1. 计算几何和质量属性: 确定气动中心位置、叶片总质量、质心等。
  2. 计算模态动力学参数: 基于模态形状函数,通过积分计算广义质量、广义刚度(包括离心刚化)、固有频率和广义阻尼。
  3. 预计算运动学辅助参数: 计算扭转形状函数及其导数,以及轴向缩短系数,这些是描述叶片柔性变形几何的关键。

这些预计算的系数 (p 结构体中的数据) 随后被其他运行时子程序高效地调用,以执行实时的运动学、力和力矩计算,并最终构建系统的运动方程。这大大提高了仿真效率,并确保了模型中物理参数的一致性和准确性。 [Timestamp: 2026/01/08 09:46:42]

user:

    flexl: f64,             // Length of the flexible beam
    mod_shp_ary: &Array1<f64>,    // Array holding mode shape coefficients
    deriv: usize            // Derivative order (0, 1, or 2)
    ) -> f64 {                  // Return type is f64 without error handling
    // Handle invalid deriv values by returning 0.0 if deriv is out of bounds
    if deriv > 2 {
        return 0.0;
    }

    // Handle invalid fract values by returning 0.0 if fract is out of bounds
    if fract < 0.0 || fract > 1.0 {
        return 0.0;
    }

    // Initialize the coefficients for the derivatives
    let mut switch = [0; 3];
    switch[deriv] = 1;

    let mut shp = 0.0;

    // Loop through all elements of mod_shp_ary
    for (i, &mod_shp_val) in mod_shp_ary.iter().enumerate() {
        let j = i + 2; // Fortran uses 1-based indexing, so adjust to 0-based for Rust
        let coef_tmp = switch[0] + switch[1] * j as i32 + switch[2] * (i as i32 + 1) * (j as i32);

        // Compute the SHP value
        if j == 2 && deriv == 2 {
            shp = mod_shp_val * coef_tmp as f64 / (flexl.powi(deriv as i32));
        } else {
            shp += mod_shp_val * coef_tmp as f64 * fract.powi((j - deriv) as i32) / (flexl.powi(deriv as i32));
        }
    }

    shp // Return the calculated SHP value
}

            bld_fl1_sh_2: -17.87632584
            bld_fl1_sh_3: 40.75086281
            bld_fl1_sh_4: -32.57060113
            bld_fl1_sh_5: 12.03110336
            bld_fl1_sh_6: -1.3350392

根据代码和系数参数,解释如何计算的模态形状函数的二阶导数
[Timestamp: 2026/01/08 10:29:43]

ai: 提供的 Rust 代码 shp_array 函数用于计算模态形状函数mode shape function及其导数。在风力机动力学模型中模态形状函数 \phi(r) 描述了柔性部件(如叶片或塔架)在特定模态下沿其长度的变形模式。

shp_array 函数的输入参数包括:

  • fract: 沿梁的无量纲距离0.0 到 1.0),表示在哪个位置计算形状函数。
  • flexl: 柔性梁的实际长度。
  • mod_shp_ary: 包含模态形状系数的数组。
  • deriv: 导数阶数0 表示形状函数本身1 表示一阶导数2 表示二阶导数)。

我们关注的是如何计算模态形状函数的二阶导数,即当 deriv = 2 时。

模态形状函数的数学表示

在 OpenFAST (ElastoDyn) 中,模态形状函数通常被表示为多项式形式,例如: \phi(x) = C_2 x^2 + C_3 x^3 + C_4 x^4 + C_5 x^5 + C_6 x^6 其中 x 是沿梁的无量纲距离(fractC_j 是模态形状系数(对应 mod_shp_ary 中的值)。

为了在实际长度 L (flexl) 上使用,通常会进行归一化,即 $r = x \cdot L$。 所以,形状函数可以写成: \phi(r) = \sum_{j=2}^{6} C_j \left(\frac{r}{L}\right)^j

shp_array 函数计算二阶导数的逻辑 (deriv = 2)

deriv = 2 时,switch 数组将是 [0, 0, 1]

让我们推导形状函数 \phi(r) 的二阶导数: \frac{d\phi}{dr} = \sum_{j=2}^{6} C_j \frac{j}{L} \left(\frac{r}{L}\right)^{j-1} \frac{d^2\phi}{dr^2} = \sum_{j=2}^{6} C_j \frac{j(j-1)}{L^2} \left(\frac{r}{L}\right)^{j-2}

现在,我们对照 shp_array 函数中的循环逻辑:

// Loop through all elements of mod_shp_ary
for (i, &mod_shp_val) in mod_shp_ary.iter().enumerate() {
    let j = i + 2; // Fortran uses 1-based indexing, so adjust to 0-based for Rust
    let coef_tmp = switch[0] + switch[1] * j as i32 + switch[2] * (i as i32 + 1) * (j as i32);

    // Compute the SHP value
    if j == 2 && deriv == 2 {
        shp = mod_shp_val * coef_tmp as f64 / (flexl.powi(deriv as i32));
    } else {
        shp += mod_shp_val * coef_tmp as f64 * fract.powi((j - deriv) as i32) / (flexl.powi(deriv as i32));
    }
}
  1. j = i + 2: 这个 j 对应于多项式项 x^j 中的指数。由于 mod_shp_ary 的索引 i 从 0 开始,而多项式从 x^2 开始,所以 j 从 2 开始。

    • i = 0 -> j = 2 (对应 C_2)
    • i = 1 -> j = 3 (对应 C_3)
    • ...
    • i = 4 -> j = 6 (对应 C_6)
  2. coef_tmp 的计算: 当 deriv = 2 时,switch = [0, 0, 1],所以 coef_tmp 简化为 (i as i32 + 1) * (j as i32)

    • i = 0, j = 2: coef_tmp = (0+1)*(2) = 2
    • i = 1, j = 3: coef_tmp = (1+1)*(3) = 6
    • i = 2, j = 4: coef_tmp = (2+1)*(4) = 12
    • i = 3, j = 5: coef_tmp = (3+1)*(5) = 20
    • i = 4, j = 6: coef_tmp = (4+1)*(6) = 30

    这些 coef_tmp 值实际上是 $j(j-1)$。

    • j=2 \implies 2(2-1) = 2
    • j=3 \implies 3(3-1) = 6
    • j=4 \implies 4(4-1) = 12
    • j=5 \implies 5(5-1) = 20
    • j=6 \implies 6(6-1) = 30 这与我们推导的二阶导数公式中的 j(j-1) 项完全一致。
  3. flexl.powi(deriv as i32): 当 deriv = 2 时,这一项是 flexl.powi(2),即 $L^2$。这也与推导公式中的 L^2 项一致。

  4. fract.powi((j - deriv) as i32): 当 deriv = 2 时,这一项是 fract.powi((j - 2) as i32),即 $x^{j-2}$。这也与推导公式中的 (r/L)^{j-2} 项一致(因为 fract 就是 $r/L$)。

  5. 特殊情况 if j == 2 && deriv == 2: 当 j=2deriv=2 时,多项式项是 $C_2 x^2$。其二阶导数是 $C_2 \frac{2}{L^2}$。 在代码中: shp = mod_shp_val * coef_tmp as f64 / (flexl.powi(deriv as i32)); mod_shp_val 是 $C_2$coef_tmp 是 2flexl.powi(deriv as i32) 是 $L^2$。 所以 shp 变为 $C_2 \cdot 2 / L^2$,这正是 C_2 x^2 的二阶导数。 注意,此时 fract.powi((j - deriv) as i32) 会是 fract.powi(0),即 1。所以 else 分支对于 j=2 的项也是正确的。这个 if 语句可能是一个优化或者为了避免 fract.powi(0) 的潜在浮点问题,但从数学上讲,两种方式都应该得到相同的结果。

结合系数参数进行计算示例

假设 flexl 是叶片柔性段的长度,fract 是沿叶片径向的无量纲位置。 给定的模态形状系数 bld_fl1_sh 对应于 mod_shp_ary

  • mod_shp_ary[0] = bld_fl1_sh_2 = -17.87632584 (对应 C_2)
  • mod_shp_ary[1] = bld_fl1_sh_3 = 40.75086281 (对应 C_3)
  • mod_shp_ary[2] = bld_fl1_sh_4 = -32.57060113 (对应 C_4)
  • mod_shp_ary[3] = bld_fl1_sh_5 = 12.03110336 (对应 C_5)
  • mod_shp_ary[4] = bld_fl1_sh_6 = -1.3350392 (对应 C_6)

假设 flexl = 10.0 米,fract = 0.5 (即在叶片柔性段的中间位置 r = 5.0 米)deriv = 2

计算过程如下:

  1. 初始化 shp = 0.0

  2. 第一次迭代 (i=0, j=2):

    • mod_shp_val = bld_fl1_sh_2 = -17.87632584
    • coef_tmp = 2(2-1) = 2
    • j == 2 && deriv == 2 为真。
    • shp = -17.87632584 * 2 / (10.0^2) = -17.87632584 * 2 / 100.0 = -0.3575265168
  3. 第二次迭代 (i=1, j=3):

    • mod_shp_val = bld_fl1_sh_3 = 40.75086281
    • coef_tmp = 3(3-1) = 6
    • j == 2 && deriv == 2 为假。
    • shp += 40.75086281 * 6 * (0.5^(3-2)) / (10.0^2)
    • shp += 40.75086281 * 6 * 0.5 / 100.0 = 40.75086281 * 3 / 100.0 = 1.2225258843
    • shp = -0.3575265168 + 1.2225258843 = 0.8649993675
  4. 第三次迭代 (i=2, j=4):

    • mod_shp_val = bld_fl1_sh_4 = -32.57060113
    • coef_tmp = 4(4-1) = 12
    • shp += -32.57060113 * 12 * (0.5^(4-2)) / (10.0^2)
    • shp += -32.57060113 * 12 * 0.25 / 100.0 = -32.57060113 * 3 / 100.0 = -0.9771180339
    • shp = 0.8649993675 - 0.9771180339 = -0.1121186664
  5. 第四次迭代 (i=3, j=5):

    • mod_shp_val = bld_fl1_sh_5 = 12.03110336
    • coef_tmp = 5(5-1) = 20
    • shp += 12.03110336 * 20 * (0.5^(5-2)) / (10.0^2)
    • shp += 12.03110336 * 20 * 0.125 / 100.0 = 12.03110336 * 2.5 / 100.0 = 0.300777584
    • shp = -0.1121186664 + 0.300777584 = 0.1886589176
  6. 第五次迭代 (i=4, j=6):

    • mod_shp_val = bld_fl1_sh_6 = -1.3350392
    • coef_tmp = 6(6-1) = 30
    • shp += -1.3350392 * 30 * (0.5^(6-2)) / (10.0^2)
    • shp += -1.3350392 * 30 * 0.0625 / 100.0 = -1.3350392 * 1.875 / 100.0 = -0.025031985
    • shp = 0.1886589176 - 0.025031985 = 0.1636269326

最终,在 fract = 0.5 处,模态形状函数的二阶导数约为 0.1636269326

Blade 笔记的联系

Blade 笔记中,模态形状函数的二阶导数在计算广义刚度时被广泛使用。例如,公式 (9) 和 (11) 中:


{k'}_{ij}^{B1F} = \sqrt{FlStTunr^{B1}(i) \, FlStTunr^{B1}(j)} \int_{0}^{BldFlexL} EI^{B1F}(r) \frac{d^2 \phi_i^{B1F}(r)}{dr^2} \frac{d^2 \phi_j^{B1F}(r)}{dr^2} dr

这里的 \frac{d^2 \phi_i^{B1F}(r)}{dr^2} 正是通过 shp_array 函数,将 deriv 设置为 2 来计算的。Coeff 子程序会遍历叶片上的所有节点,在每个节点处调用 shp_array 来获取模态形状函数的二阶导数,然后将这些值与叶片刚度 EI^{B1F}(r) 相乘并进行数值积分,从而得到广义刚度。

因此,shp_array 函数是风力机柔性体动力学建模中一个核心的数学工具,它将抽象的模态形状函数定义转化为具体的数值计算,为广义刚度、广义质量等关键参数的计算提供了基础。 [Timestamp: 2026/01/08 10:30:08]

user: 展开形状函数的推导公式每一项,以多项式的形式解释,不要用连加符号 [Timestamp: 2026/01/08 10:36:21]

ai: 好的,我将根据提供的 shp_array Rust 代码和模态形状系数,以多项式形式展开模态形状函数的二阶导数,不使用连加符号。

模态形状函数的多项式形式

首先,我们假设模态形状函数 \phi(x) 的基本多项式形式为: \phi(x) = C_2 x^2 + C_3 x^3 + C_4 x^4 + C_5 x^5 + C_6 x^6

其中 x 是沿梁的无量纲距离 fract,其范围是 。 系数 C_j 对应于 mod_shp_ary 中的值:

  • C_2 = \text{bld\_fl1\_sh\_2} = -17.87632584
  • C_3 = \text{bld\_fl1\_sh\_3} = 40.75086281
  • C_4 = \text{bld\_fl1\_sh\_4} = -32.57060113
  • C_5 = \text{bld\_fl1\_sh\_5} = 12.03110336
  • C_6 = \text{bld\_fl1\_sh\_6} = -1.3350392

模态形状函数的一阶导数

\phi(x) 求关于 x 的一阶导数: \frac{d\phi}{dx} = \frac{d}{dx}(C_2 x^2 + C_3 x^3 + C_4 x^4 + C_5 x^5 + C_6 x^6) \frac{d\phi}{dx} = 2 C_2 x^1 + 3 C_3 x^2 + 4 C_4 x^3 + 5 C_5 x^4 + 6 C_6 x^5

模态形状函数的二阶导数

\frac{d\phi}{dx} 求关于 x 的一阶导数,即 \phi(x) 的二阶导数: \frac{d^2\phi}{dx^2} = \frac{d}{dx}(2 C_2 x^1 + 3 C_3 x^2 + 4 C_4 x^3 + 5 C_5 x^4 + 6 C_6 x^5) \frac{d^2\phi}{dx^2} = 2 \cdot 1 \cdot C_2 x^0 + 3 \cdot 2 \cdot C_3 x^1 + 4 \cdot 3 \cdot C_4 x^2 + 5 \cdot 4 \cdot C_5 x^3 + 6 \cdot 5 \cdot C_6 x^4 \frac{d^2\phi}{dx^2} = 2 C_2 + 6 C_3 x + 12 C_4 x^2 + 20 C_5 x^3 + 30 C_6 x^4

考虑实际长度 flexl

shp_array 函数中,导数是相对于实际长度 flexl 进行归一化的。如果 \phi(r) 是关于实际距离 r 的函数,且 $x = r / \text{flexl}$,那么: \frac{d\phi}{dr} = \frac{d\phi}{dx} \frac{dx}{dr} = \frac{d\phi}{dx} \frac{1}{\text{flexl}} \frac{d^2\phi}{dr^2} = \frac{d}{dr}\left(\frac{d\phi}{dx} \frac{1}{\text{flexl}}\right) = \frac{1}{\text{flexl}} \frac{d}{dr}\left(\frac{d\phi}{dx}\right) = \frac{1}{\text{flexl}} \frac{d}{dx}\left(\frac{d\phi}{dx}\right) \frac{dx}{dr} = \frac{1}{\text{flexl}^2} \frac{d^2\phi}{dx^2}

所以,模态形状函数关于实际长度 r 的二阶导数 \frac{d^2\phi}{dr^2} 的多项式形式为: \frac{d^2\phi}{dr^2} = \frac{1}{\text{flexl}^2} (2 C_2 + 6 C_3 x + 12 C_4 x^2 + 20 C_5 x^3 + 30 C_6 x^4)

fract 代替 $x$,并代入具体的系数:

\frac{d^2\phi}{dr^2} = \frac{1}{\text{flexl}^2} \left( 2 \cdot (-17.87632584) \right. \quad + 6 \cdot (40.75086281) \cdot \text{fract} \quad + 12 \cdot (-32.57060113) \cdot \text{fract}^2 \quad + 20 \cdot (12.03110336) \cdot \text{fract}^3 \quad \left. + 30 \cdot (-1.3350392) \cdot \text{fract}^4 \right)

展开每一项:

\frac{d^2\phi}{dr^2} = \frac{1}{\text{flexl}^2} \left( -35.75265168 \right. \quad + 244.50517686 \cdot \text{fract} \quad - 390.84721356 \cdot \text{fract}^2 \quad + 240.62206720 \cdot \text{fract}^3 \quad \left. - 40.05117600 \cdot \text{fract}^4 \right)

shp_array 代码的对应关系

我们来验证这个展开式与 shp_array 代码的逻辑是否一致:

shp_array 函数中,当 deriv = 2 时:

  • coef_tmp 的计算结果是 $j(j-1)$。
  • mod_shp_val 是 $C_j$。
  • fract.powi((j - deriv) as i32) 是 $x^{j-2}$。
  • flexl.powi(deriv as i32) 是 $\text{flexl}^2$。

所以,shp 的累加项是: mod_shp_val * coef_tmp * fract.powi(j - 2) / flexl.powi(2) 这正是 $C_j \cdot j(j-1) \cdot x^{j-2} / \text{flexl}^2$。

mod_shp_ary 中的每个系数代入,并按照 j 的顺序展开:

  • 对于 C_2 (i=0, j=2): C_2 \cdot 2(2-1) \cdot \text{fract}^{2-2} / \text{flexl}^2 = C_2 \cdot 2 \cdot \text{fract}^0 / \text{flexl}^2 = 2 C_2 / \text{flexl}^2 = 2 \cdot (-17.87632584) / \text{flexl}^2 = -35.75265168 / \text{flexl}^2

  • 对于 C_3 (i=1, j=3): C_3 \cdot 3(3-1) \cdot \text{fract}^{3-2} / \text{flexl}^2 = C_3 \cdot 6 \cdot \text{fract}^1 / \text{flexl}^2 = 6 \cdot (40.75086281) \cdot \text{fract} / \text{flexl}^2 = 244.50517686 \cdot \text{fract} / \text{flexl}^2

  • 对于 C_4 (i=2, j=4): C_4 \cdot 4(4-1) \cdot \text{fract}^{4-2} / \text{flexl}^2 = C_4 \cdot 12 \cdot \text{fract}^2 / \text{flexl}^2 = 12 \cdot (-32.57060113) \cdot \text{fract}^2 / \text{flexl}^2 = -390.84721356 \cdot \text{fract}^2 / \text{flexl}^2

  • 对于 C_5 (i=3, j=5): C_5 \cdot 5(5-1) \cdot \text{fract}^{5-2} / \text{flexl}^2 = C_5 \cdot 20 \cdot \text{fract}^3 / \text{flexl}^2 = 20 \cdot (12.03110336) \cdot \text{fract}^3 / \text{flexl}^2 = 240.62206720 \cdot \text{fract}^3 / \text{flexl}^2

  • 对于 C_6 (i=4, j=6): C_6 \cdot 6(6-1) \cdot \text{fract}^{6-2} / \text{flexl}^2 = C_6 \cdot 30 \cdot \text{fract}^4 / \text{flexl}^2 = 30 \cdot (-1.3350392) \cdot \text{fract}^4 / \text{flexl}^2 = -40.05117600 \cdot \text{fract}^4 / \text{flexl}^2

将这些项相加,就得到了模态形状函数二阶导数的完整多项式形式,与我们之前推导的完全一致。

结论:

模态形状函数的二阶导数 \frac{d^2\phi}{dr^2} 可以表示为以下多项式形式:

\frac{d^2\phi}{dr^2} = \frac{1}{\text{flexl}^2} \left( (-35.75265168) \right. \quad + (244.50517686) \cdot \text{fract} \quad + (-390.84721356) \cdot \text{fract}^2 \quad + (240.62206720) \cdot \text{fract}^3 \quad \left. + (-40.05117600) \cdot \text{fract}^4 \right)

其中:

  • flexl 是叶片的柔性长度。
  • fract 是沿叶片径向的无量纲距离0 到 1
  • 括号内的数值是模态形状系数 C_j 乘以对应的导数因子 $j(j-1)$。

这个展开式清晰地展示了 shp_array 函数在 deriv = 2 时如何根据输入的模态形状系数和位置,计算出模态形状函数的二阶导数。 [Timestamp: 2026/01/08 10:36:43]

user: bld_fl1_sh_2: -17.87632584 bld_fl1_sh_3: 40.75086281 bld_fl1_sh_4: -32.57060113 bld_fl1_sh_5: 12.03110336 bld_fl1_sh_6: -1.3350392 bld_fl2_sh_2: -61.72252055 bld_fl2_sh_3: 150.47443903 bld_fl2_sh_4: -123.2723888 bld_fl2_sh_5: 40.42018428 bld_fl2_sh_6: -4.89971395 bld_edg_sh_2: -22.64325886 bld_edg_sh_3: 53.64951962 bld_edg_sh_4: -44.37014633 bld_edg_sh_5: 15.82350193 bld_edg_sh_6: -1.45961636 三条形状如何画出来看 [Timestamp: 2026/01/08 11:08:55]

ai: 好的,为了绘制这三条模态形状函数,我们需要使用 shp_array 函数来计算它们在叶片不同径向位置上的值。

模态形状函数的基本多项式形式为: \phi(x) = C_2 x^2 + C_3 x^3 + C_4 x^4 + C_5 x^5 + C_6 x^6 其中 x 是无量纲距离 fract (从 0 到 1)。

为了绘制这些形状,我们需要:

  1. 定义一个 shp_array 函数的实现(这里我们使用之前提供的 Rust 代码的逻辑)。
  2. 为每个模态形状函数提供其对应的系数数组。
  3. 选择一个 flexl 值(叶片柔性段的长度)。
  4. fract 范围 内取一系列点。
  5. 对于每个 fract 值,调用 shp_array 函数(deriv = 0,因为我们要绘制形状本身,而不是其导数)。
  6. 将结果绘制出来。

1. shp_array 函数的逻辑(用于 deriv = 0

deriv = 0 时,switch 数组将是 [1, 0, 0]coef_tmp 的计算简化为 switch[0],即 1。 flexl.powi(deriv as i32) 简化为 flexl.powi(0),即 1。 fract.powi((j - deriv) as i32) 简化为 fract.powi(j as i32),即 $x^j$。

所以,shp 的累加项是: mod_shp_val * 1 * fract.powi(j) / 1 这正是 $C_j \cdot x^j$。

因此,shp_array(fract, flexl, mod_shp_ary, 0) 将计算: \phi(x) = C_2 x^2 + C_3 x^3 + C_4 x^4 + C_5 x^5 + C_6 x^6

2. 模态形状系数

我们有三组系数:

a) 第一阶挥舞模态 (bld_fl1_sh):

  • C_2 = -17.87632584
  • C_3 = 40.75086281
  • C_4 = -32.57060113
  • C_5 = 12.03110336
  • C_6 = -1.3350392

b) 第二阶挥舞模态 (bld_fl2_sh):

  • C_2 = -61.72252055
  • C_3 = 150.47443903
  • C_4 = -123.2723888
  • C_5 = 40.42018428
  • C_6 = -4.89971395

c) 第一阶摆振模态 (bld_edg_sh):

  • C_2 = -22.64325886
  • C_3 = 53.64951962
  • C_4 = -44.37014633
  • C_5 = 15.82350193
  • C_6 = -1.45961636

3. 绘制方法

为了绘制这些形状,你可以使用任何支持科学绘图的编程语言或工具,例如 Python (matplotlib/numpy)、MATLAB、R、Julia 等。

以下是使用 Python 的示例代码和步骤:

步骤:

  1. 定义 shp_array 函数Python 实现):

    import numpy as np
    import matplotlib.pyplot as plt
    
    def shp_array_python(fract, flexl, mod_shp_ary, deriv):
        if deriv > 2 or fract < 0.0 or fract > 1.0:
            return 0.0
    
        switch = [0, 0, 0]
        switch[deriv] = 1
    
        shp = 0.0
    
        for i, mod_shp_val in enumerate(mod_shp_ary):
            j = i + 2 # Corresponds to x^j in the polynomial
            coef_tmp = switch[0] + switch[1] * j + switch[2] * (i + 1) * j
    
            if j == 2 and deriv == 2:
                # Special case for x^2 term's second derivative
                shp_term = mod_shp_val * coef_tmp / (flexl**deriv)
            else:
                # General case for any derivative
                shp_term = mod_shp_val * coef_tmp * (fract**(j - deriv)) / (flexl**deriv)
    
            shp += shp_term
        return shp
    
  2. 定义模态形状系数数组:

    # 假设 flexl = 1.0 (无量纲化因为形状函数本身就是无量纲的通常在绘图时将flexl设为1)
    # 如果需要绘制实际物理长度上的形状则flexl应为实际叶片柔性段长度例如 60 米。
    # 这里我们先绘制无量纲形状,所以 flexl=1.0fract 对应 r/L
    flexl_val = 1.0 
    
    # 第一阶挥舞模态 (bld_fl1_sh)
    bld_fl1_sh = np.array([
        -17.87632584,  # C2
        40.75086281,   # C3
        -32.57060113,  # C4
        12.03110336,   # C5
        -1.3350392     # C6
    ])
    
    # 第二阶挥舞模态 (bld_fl2_sh)
    bld_fl2_sh = np.array([
        -61.72252055,
        150.47443903,
        -123.2723888,
        40.42018428,
        -4.89971395
    ])
    
    # 第一阶摆振模态 (bld_edg_sh)
    bld_edg_sh = np.array([
        -22.64325886,
        53.64951962,
        -44.37014633,
        15.82350193,
        -1.45961636
    ])
    
  3. 生成 fract 值范围:

    fract_values = np.linspace(0.0, 1.0, 100) # 从 0 到 1 取 100 个点
    
  4. 计算每个模态形状函数的值:

    # 计算第一阶挥舞模态形状
    fl1_shape = [shp_array_python(f, flexl_val, bld_fl1_sh, 0) for f in fract_values]
    
    # 计算第二阶挥舞模态形状
    fl2_shape = [shp_array_python(f, flexl_val, bld_fl2_sh, 0) for f in fract_values]
    
    # 计算第一阶摆振模态形状
    edg_shape = [shp_array_python(f, flexl_val, bld_edg_sh, 0) for f in fract_values]
    
  5. 绘制图形:

    plt.figure(figsize=(10, 6))
    plt.plot(fract_values * flexl_val, fl1_shape, label='First Flapwise Mode')
    plt.plot(fract_values * flexl_val, fl2_shape, label='Second Flapwise Mode')
    plt.plot(fract_values * flexl_val, edg_shape, label='First Edgewise Mode')
    
    plt.title('Blade Mode Shapes')
    plt.xlabel('Fractional Blade Length (r/L)')
    plt.ylabel('Mode Shape Amplitude')
    plt.grid(True)
    plt.legend()
    plt.show()
    

解释绘制出的形状

绘制出的图形将展示这三种模态形状函数沿叶片长度的变形模式:

  • 第一阶挥舞模态 (First Flapwise Mode): 通常表现为叶片在挥舞方向(垂直于旋转平面)的第一次弯曲。形状会从叶根(fract=0)处的零位移开始,逐渐增加到最大位移,然后可能在叶尖附近再次减小(取决于边界条件和模态阶数)。对于风力机叶片,通常是单弯曲形状,叶尖位移最大。

  • 第二阶挥舞模态 (Second Flapwise Mode): 表现为叶片在挥舞方向的第二次弯曲。与第一阶模态不同,第二阶模态通常会有一个或多个“节点”(位移为零的点)沿叶片长度方向。这意味着叶片会形成 S 形或更复杂的弯曲模式,在叶尖处可能再次达到一个峰值。

  • 第一阶摆振模态 (First Edgewise Mode): 表现为叶片在摆振方向(平行于旋转平面)的第一次弯曲。与挥舞模态类似,它通常也是单弯曲形状,叶尖位移最大。由于摆振方向的刚度通常远大于挥舞方向,所以相同幅度的广义坐标下,摆振模态的物理位移可能较小,或者其固有频率较高。

通过可视化这些形状,你可以直观地理解在这些特定模态下,叶片是如何变形的,这对于理解叶片的动力学响应和设计优化至关重要。 [Timestamp: 2026/01/08 11:09:10]