obsidian_backup/copilot-conversations/20251105_143348__[[Drivetrain]]详细分析推导内容.md

70 KiB
Raw Permalink Blame History

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

user: Drivetrain详细分析推导内容 [Timestamp: 2025/11/05 14:33:48]

ai: 好的,我们来对 Drivetrain 这篇笔记进行详细的分析和推导说明。

这篇笔记的核心目标是建立风力发电机传动系统Drivetrain的动力学方程。它采用拉格朗日力学的方法通过分析传动系统各个部件产生的广义力Generalized Forces,最终将它们整合到统一的运动方程中。

整个系统的运动方程可以抽象为以下形式: [C(q,t)]\ddot{q} = -f(\dot{q},q,t) 其中:

  • q 是系统的广义坐标向量(代表各个自由度,如发电机转角 $q_{GeAz}$、轴的扭转角 q_{DrTr} 等)。
  • [C(q,t)] 是系统的质量矩阵(或称惯性矩阵),它与广义加速度 \ddot{q} 相关。
  • \{-f(\dot{q},q,t)\}广义力向量,包含了所有不依赖于加速度的力,如外力、阻尼力、弹性力、科里奥利力等。

笔记的内容就是逐一分析传动系统中不同物理效应如何贡献到 [C(q,t)]\{-f(\dot{q},q,t)\} 这两个项中。


各个部件的力学分析推导

1. 发电机Generator的广义主动力

  • 物理作用:发电机将机械能转化为电能,对高速轴施加一个阻力矩。这个力矩是主动控制的,大小取决于发电机的控制策略和当前的转速。
  • 推导过程
    1. 公式 (3) 定义了发电机产生的机械扭矩向量 $\boldsymbol{M_{G e n}^{G}}$。它作用在高速轴上,方向为 $-c_1$(假设 c_1 是轴的正方向),大小为 $T^{G e n}$。GenDir 决定了发电机旋转方向与低速轴的关系(通常为-1T^{G e n} 为正值时代表发电(负载),为负值时代表电机模式(输入功率)。
    2. 广义力 F_r 是通过虚功原理计算的,等于扭矩向量和广义速率向量 {^{E}\pmb{\omega}_{r}^{G}} 的点积。
    3. 由于发电机扭矩只影响传动链的旋转所以它只对发电机方位角自由度Generator Azimuth DOF, $r=GeAz$)有贡献。
    4. 公式 (4) 和 (5) 计算了这个广义力。将 {^{E}\pmb{\omega}_{G e d z}^{G}} = GenDir \cdot GBRatio \cdot c_1\boldsymbol{M_{G e n}^{G}} 代入,得到最终结果 $F_{GeAz}|_{Gen} = -GBRatio \cdot T^{Gen}$。
      • $GBRatio$(齿轮箱速比)将高速轴的扭矩转换到了低速轴侧。
      • 负号表示这是一个阻力,与转子旋转方向相反。
  • 对系统方程的贡献
    • 这个力不依赖于加速度 $\ddot{q}$,因此它被放入广义力向量 \{-f(\dot{q},q,t)\} 中,如公式 (7) 所示。
    • 它对质量矩阵 [C(q,t)] 没有贡献,如公式 (6) 所示。

2. 高速轴制动器HSS Brake的广义主动力

  • 物理作用:高速轴制动器施加一个机械摩擦力矩,用于刹停或控制转速。
  • 推导过程
    • 这个推导过程与发电机完全类似。制动器扭矩 $T^{Brake}$(公式 9被认为始终为正值总是起制动作用
    • 通过与发电机相同的逻辑,在公式 (10) 中得到其对发电机方位角自由度的广义力为 $F_{GeAz}|_{Brake} = -GBRatio \cdot T^{Brake}(t)$。
  • 对系统方程的贡献
    • 同样,这是一个不依赖于加速度的力,贡献给广义力向量 ${-f(\dot{q},q,t)}$(公式 12
    • 对质量矩阵 [C(q,t)] 没有贡献(公式 11

3. 发电机惯性Generator Inertia的广义惯性力

  • 物理作用:发电机自身拥有转动惯量($GenIner$),它的角加速度和角速度变化会产生惯性力(陀螺效应等)。
  • 推导过程
    1. 公式 (13) 是广义惯性力 F_r^* 的标准表达式,它等于惯性力/力矩(括号中的项)与广义速率向量的点积。括号中的项是牛顿-欧拉方程的惯性项,包括线性惯性项 (-\overline{\overline{{I}}}^{\text{G}} \cdot {}^E {a}^{\text{G}}) 和非线性速度项(陀螺力矩, $- {}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}})$。
    2. 公式 (14) 到 (17) 是将角加速度 {}^E {a}^{\text{G}} 和角速度 {}^E \boldsymbol{\omega}^{\text{G}} 用广义坐标 q_i 及其导数表示,并进行化简。
    3. 一个关键的化简是 $c_{1}\cdot({}^E\omega^{G}\times c_{1})=0$,这是因为发电机的惯性张量 \overline{\overline{{I}}}^{\text{G}} 只有一个沿着旋转轴 c_1 的分量 $GenIner$。这意味着垂直于旋转轴的陀螺力矩对该自由度的贡献为零。
  • 对系统方程的贡献
    • 质量矩阵 $[C(q,t)]$:惯性力中包含与广义加速度 \ddot{q}_i 相关的项。这些项的系数构成了质量矩阵的一部分,如公式 (18) 所示。例如,对角线上的 C_{13,13} 项就包含了 GenIner \cdot GBRatio^2 这一项,这正是将高速轴发电机惯量折算到低速轴侧的结果。
    • 广义力向量 ${-f(\dot{q},q,t)}$:惯性力中也包含与广义速度 \dot{q}_i 相关的项(如科里奥利力、向心力等)。这些项被归入广义力向量中,如公式 (19) 所示。

4. 传动轴弹性Elastic Drive和阻尼Damp Drive

  • 物理作用:低速轴不是完全刚性的,它具有扭转弹性和扭转阻尼。
    • 弹性:由扭转弹簧系数 DTTorSpr 描述,产生与扭转角 q_{DrTr} 成正比的恢复力矩。
    • 阻尼:由扭转阻尼系数 DTTorDmp 描述,产生与扭转角速度 \dot{q}_{DrTr} 成正比的阻尼力矩。
  • 推导过程
    1. 弹性势能为 $V_{Drive} = \frac{1}{2} DTTorSpr \cdot q_{DrTr}^2$(公式 20。广义力是势能对广义坐标的负偏导数因此 $F_{DrTr}|{ElasticDrive} = -DTTorSpr \cdot q{DrTr}$(公式 21
    2. 阻尼力直接定义为与速度成正比,方向相反,即 $F_{DrTr}|{DampDrive} = -DTTorDmp \cdot \dot{q}{DrTr}$(公式 22
  • 对系统方程的贡献
    • 这两个力都不依赖于加速度,因此它们都贡献给广义力向量 ${-f(\dot{q},q,t)}$(公式 24 和 26
    • 它们对质量矩阵没有贡献(公式 23 和 25

5. 齿轮箱摩擦Gearbox Friction

  • 物理作用:齿轮箱存在效率损失($GBoxEff < 100%$),这表现为作用在传动链上的一个摩擦力矩。这个摩擦力矩的大小与通过齿轮箱传递的扭矩有关。
  • 推导过程
    1. 这是整个推导中最复杂也最关键的部分。公式 (28) 定义了摩擦力矩 $T^{\text{GBFric}}$。它等于作用在高速轴上的总扭矩乘以一个与齿轮箱效率相关的系数。
    2. 高速轴上的总扭矩包括:发电机惯性产生的扭矩、发电机电磁扭矩和高速轴制动器扭矩。
    3. 效率系数为 $[\frac{1}{GBoxEff^{\text{SIGN(LSShftTq)}}} - 1]$。SIGN(LSShftTq) 项非常重要,它表示效率损失的方向取决于功率流动的方向(是从转子到发电机,还是反过来)。
    4. 公式 (30) 和 (31) 将这个摩擦力矩表达为广义力。
  • 对系统方程的贡献
    • 质量矩阵 $[C(q,t)]$:观察公式 (31) 可以发现,摩擦力矩 T^{\text{GBFric}} 的表达式中包含了广义加速度项 \ddot{q}_{GeAz} 和其他 $\ddot{q}_i$。这意味着摩擦力本身依赖于系统的加速度。因此,它会贡献给质量矩阵,如公式 (32) 所示。
    • 非对称质量矩阵:由于这个贡献,质量矩阵 [C(q,t)] 变得非对称。这是因为摩擦力是一个非保守力,它的贡献不具有对称性。这是整个系统动力学模型中一个非常重要的特性。
    • 广义力向量 ${-f(\dot{q},q,t)}$:摩擦力矩中不依赖于加速度的部分(如与发电机扭矩、制动器扭矩、速度相关的惯性项等)则贡献给广义力向量,如公式 (33) 所示。
    • 隐式方程问题:由于摩擦力是当前时刻加速度的函数,而它本身又作为力出现在运动方程中,这导致了一个隐式方程implicit equation求解困难。笔记中提到为了简化计算采用了一个近似方法使用上一个时间步的低速轴扭矩 LSShftTq 来判断 SIGN 函数的符号,从而避免了在当前时间步内进行迭代求解。

总结

这篇笔记通过对传动系统各个部件(发电机、制动器、轴的弹性和阻尼、齿轮箱摩擦)产生的力/力矩进行逐一分析,系统地构建了整个传动系统的动力学方程。

其核心思想是:

  1. 分解与合成:将复杂的系统分解为多个物理效应的叠加。
  2. 广义力:将每个物理效应产生的力或力矩,通过虚功原理转化为对相应广义坐标的广义力。
  3. 方程构建:根据广义力是否与广义加速度 \ddot{q} 相关,将其分别归入质量矩阵 [C(q,t)] 或广义力向量 ${-f(\dot{q},q,t)}$。
  4. 关键洞察:明确指出了齿轮箱摩擦是导致系统质量矩阵非对称的根源,并解释了如何通过数值近似来处理由此带来的隐式方程问题。

最终,将所有这些部件的贡献相加,就得到了传动系统完整的、高度耦合的非线性动力学模型。 [Timestamp: 2025/11/05 14:34:31]

user: Drivetrain发电机Generator的广义主动力中的c_{1}从公式四到五,怎么没了 [Timestamp: 2025/11/05 14:46:36]

ai: 您好,这是一个非常好的问题,也是理解向量运算在动力学推导中应用的关键点。

从公式 (4) 到公式 (5),向量 c_1 之所以“消失”,是因为公式 (4) 本质上是一个向量点积Dot Product运算,而点积的结果是一个标量Scalar,不再是向量。

我们来详细分解一下这个过程:

1. 理解公式 (4) 的结构

公式 (4) 的表达式是: F_{r}\Big|_{G e n} = \left(G e n D i r\cdot G B R a t i o\cdot \boldsymbol{c}_{1}\right)\cdot\left[-G e n D i r\cdot T^{G e n}\left(\dots\right)\boldsymbol{c}_{1}\right]

这个公式是两个向量的点积:

  • 向量一: {^{E}\pmb{\omega}_{G e A z}^{G}} = (GenDir \cdot GBRatio) \cdot \boldsymbol{c}_{1}
    • 这是一个角速度向量。(GenDir \cdot GBRatio) 是一个标量,\boldsymbol{c}_{1} 是表示旋转轴方向的单位向量
  • 向量二: \boldsymbol{M_{G e n}^{G}} = [-GenDir \cdot T^{Gen}(\dots)] \cdot \boldsymbol{c}_{1}
    • 这是一个力矩向量。[-GenDir \cdot T^{Gen}(\dots)] 是一个标量,\boldsymbol{c}_{1} 是表示力矩作用方向的单位向量

2. 向量点积的运算规则

向量点积的核心规则是:$\vec{A} \cdot \vec{B} = |\vec{A}| |\vec{B}| \cos(\theta)$。 当两个向量方向相同时,例如两个向量都是沿着单位向量 \boldsymbol{c}_{1} 的方向,那么它们之间的夹角 $\theta = 0$,并且 $\cos(0) = 1$。

一个更直接的规则是,对于单位向量 $\boldsymbol{c}{1}$,它与自身的点积为: \boldsymbol{c}_{1} \cdot \boldsymbol{c}_{1} = 1 因为单位向量的模长为1所以 $| \boldsymbol{c}{1} | \cdot | \boldsymbol{c}_{1} | \cdot \cos(0) = 1 \cdot 1 \cdot 1 = 1$。

3. 推导过程

现在,我们将点积运算规则应用到公式 (4) 中:

  1. 将标量部分提取出来 F_{r}\Big|_{G e n} = (GenDir \cdot GBRatio) \cdot (-GenDir \cdot T^{Gen}(\dots)) \cdot (\boldsymbol{c}_{1} \cdot \boldsymbol{c}_{1})

  2. 计算单位向量的点积 我们知道 $\boldsymbol{c}{1} \cdot \boldsymbol{c}{1} = 1$。所以上式变为: F_{r}\Big|_{G e n} = (GenDir \cdot GBRatio) \cdot (-GenDir \cdot T^{Gen}(\dots)) \cdot 1

  3. 合并和化简标量 F_{r}\Big|_{G e n} = - (GenDir \cdot GenDir) \cdot GBRatio \cdot T^{Gen}(\dots) F_{r}\Big|_{G e n} = - (GenDir^2) \cdot GBRatio \cdot T^{Gen}(\dots)

  4. 利用已知条件 笔记中明确提到 "since $GenDir^2 = 1$"。因为 GenDir 的值是 +1 或 -1它的平方永远是 1。所以 F_{r}\Big|_{G e n} = - (1) \cdot GBRatio \cdot T^{Gen}(\dots)

  5. 得到最终结果 F_{r}\Big|_{G e n} = - GBRatio \cdot T^{Gen}(GBRatio \cdot \dot{q}_{GeAz}, t)

这个结果就和公式 (5) 完全一致了。

总结

简单来说,从公式 (4) 到 (5) 的推导步骤是:

  1. 执行两个向量的点积运算。
  2. 由于两个向量方向相同(都在 \boldsymbol{c}_{1} 方向上),它们的单位向量部分 \boldsymbol{c}_{1} \cdot \boldsymbol{c}_{1} 的点积结果为 1。
  3. 剩下的标量部分相乘并化简(利用 $GenDir^2=1$),最终得到一个标量结果。

这个过程在物理上的意义是:广义力 F_r 是一个标量,它表示力矩在广义坐标方向上所做的虚功。通过点积运算,我们将向量形式的力矩和角速度转换为了标量形式的广义力。 [Timestamp: 2025/11/05 14:47:02]

user: Drivetrain展开公式13-17的推导过程 [Timestamp: 2025/11/05 14:57:25]

ai: 好的,我们来详细地展开并推导从公式 (13) 到 (17) 的过程。这个过程是计算由发电机转动惯量产生的广义惯性力,是整个动力学建模中的核心部分之一。

基础:公式 (13) - 广义惯性力的定义

我们从最基础的公式开始:


F_r^*|_{\text{G}} = {}^E \omega_r^{\text{G}} \cdot (-\overline{\overline{{I}}}^{\text{G}} \cdot {}^E {a}^{\text{G}} - {}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}}) \quad\left(r=1,2,...,22\right)\tag{13}

这个公式的含义是:

  • $F_r^*|_{\text{G}}$:由发电机惯性产生的、作用于第 r 个自由度DOF上的广义惯性力。
  • ${}^E \omega_r^{\text{G}}$:与第 r 个广义坐标 \dot{q}_r 相关的偏角速度向量。它表示当只有 \dot{q}_r=1 而其他广义速度为0时发电机的角速度。
  • 括号里的项是发电机受到的惯性力矩,源自牛顿-欧拉方程,包括:
    • $-\overline{\overline{{I}}}^{\text{G}} \cdot {}^E {a}^{\text{G}}$:由角加速度 {}^E {a}^{\text{G}} 产生的线性惯性力矩。
    • $- {}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}}$:由角速度 {}^E \boldsymbol{\omega}^{\text{G}} 产生的非线性(陀螺)惯性力矩。
  • $\overline{\overline{{I}}}^{\text{G}}$:发电机的惯性张量。对于一个绕 c_1 轴对称的转子,它可以简化为 $\overline{\overline{{I}}}^{\text{G}} = GenIner \cdot c_1 c_1$。这意味着它只在 c_1 轴方向有惯量 $GenIner$。

步骤 1: 从 (13) 到 (14) - 展开角加速度

为了计算,我们需要将抽象的角加速度 {}^E {a}^{\text{G}} 用广义坐标的二阶导数 \ddot{q}_i 来表示。

发电机的绝对角速度 {}^E \boldsymbol{\omega}^{\text{G}} 是所有影响它的自由度DOFs 4-13的偏角速度的线性叠加 {}^E \boldsymbol{\omega}^{\text{G}} = \sum_{i=4}^{13} {}^E \boldsymbol{\omega}_i^{\text{G}} \dot{q}_i

对时间求导得到绝对角加速度 ${}^E {a}^{\text{G}}$,使用乘法法则: {}^E {a}^{\text{G}} = \frac{d}{dt} \left( \sum_{i=4}^{13} {}^E \boldsymbol{\omega}_i^{\text{G}} \dot{q}_i \right) = \sum_{i=4}^{13} \left( {}^E \boldsymbol{\omega}_i^{\text{G}} \ddot{q}_i + \frac{d}{dt}({}^E \boldsymbol{\omega}_i^{\text{G}}) \dot{q}_i \right)

将这个展开式代入公式 (13) 中的 ${}^E {a}^{\text{G}}$,就得到了公式 (14)


F_r^*|_{\text{G}} = {}^E \boldsymbol{\omega}_r^{\text{G}} \cdot \left\{ -\overline{\overline{{I}}}^{\text{G}} \cdot \left\{ \left( \sum_{i=4}^{13} {}^E \omega_i^{\text{G}} \ddot{q}_i \right) + \left[ \sum_{i=7}^{13} \frac{d}{dt} \left( {}^E \boldsymbol{\omega}_i^{\text{G}} \right) \dot{q}_i \right] \right\} - {}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}} \right\} \tag{14}

(注第二个求和的下标从7开始是因为DOFs 4, 5, 6 对应的偏角速度向量是常数,其时间导数为零。)


步骤 2: 从 (14) 到 (15) - 第一次化简

笔记中给出了一个关键的化简条件: c_{1}\cdot\frac{d}{d t}({}^{E}\omega_{G e A z}^{G}) \propto c_{1}\cdot({}^{E}\omega^{R}\times c_{1})={^{E}\omega^{R}}\cdot(c_{1}\times c_{1})=0

这个化简是针对公式 (14) 中第二个求和项里 i=13 (即 GeAz 自由度) 的情况。

  1. 发电机自由度 GeAz 对应的偏角速度 {}^{E}\omega_{G e A z}^{G} 是沿着旋转轴 c_1 的,即 ${}^{E}\omega_{G e A z}^{G} \propto c_1$。
  2. 它的时间导数 \frac{d}{dt}(c_1) 是由于整个转子/机舱的运动(角速度为 ${}^{E}\omega^{R}$)引起的,等于 ${}^{E}\omega^{R} \times c_1$。
  3. 在公式 (14) 中,这一项需要先与惯性张量 \overline{\overline{{I}}}^{\text{G}} 作用。因为 \overline{\overline{{I}}}^{\text{G}} 只在 c_1 方向有分量,所以 \overline{\overline{{I}}}^{\text{G}} \cdot \frac{d}{dt}({}^{E}\omega_{G e A z}^{G}) 的结果是一个沿着 c_1 方向的向量。
  4. 整个表达式最终会变成 $... \cdot (c_1 \cdot \frac{d}{dt}({}^{E}\omega_{G e A z}^{G})) \propto c_1 \cdot ({}^{E}\omega^{R} \times c_1)$。
  5. 根据向量混合积的性质,$c_1 \cdot ({}^{E}\omega^{R} \times c_1) = {}^{E}\omega^{R} \cdot (c_1 \times c_1)$。
  6. 任何向量与自身的叉乘都为零,即 $c_1 \times c_1 = 0$。
  7. 因此,求和项中 i=13 这一项为零。

所以第二个求和的上标可以从13改为12这就得到了公式 (15)。


步骤 3: 从 (15) 到 (16) - 分情况讨论

现在,我们需要根据广义力 F_r^* 的下标 r 来分情况计算。

情况一: r = 4, 5, ..., 12 (影响机舱和转子姿态的自由度) 对于这些自由度,发电机的运动完全跟随转子/机舱的运动,因此它们的偏角速度是相同的:${}^E \boldsymbol{\omega}_r^{\text{G}} = {}^E \boldsymbol{\omega}_r^{\text{R}}$。 将这个关系直接代入公式 (15) 的最左边,就得到了公式 (16) 的第一种情况。这表示的是发电机的惯性(陀螺效应等)对整个支撑结构产生的反作用力矩。

情况二: r = GeAz (发电机自身的旋转自由度, DOF 13) 这时,我们需要计算当 r=13 时的点积。

  1. 此时的偏角速度为 ${}^E \boldsymbol{\omega}_{GeAz}^{\text{G}} = GenDir \cdot GBRatio \cdot c_1$。
  2. 我们将这个向量与公式 (15) 中大括号内的每一项进行点积。
    • 与加速度项的点积: {}^E \boldsymbol{\omega}_{GeAz}^{\text{G}} \cdot (-\overline{\overline{{I}}}^{\text{G}} \cdot \sum_{i=4}^{13} {}^E \omega_i^{\text{G}} \ddot{q}_i) 这个求和可以拆成 i=4,...,12i=13 两部分。
      • i=4,...,12 部分: 得到 $- GenDir \cdot GenIner \cdot GBRatio \cdot c_1 \cdot \left{ \sum_{i=4}^{12} {}^E \boldsymbol{\omega}_i^{\text{R}} \ddot{q}_i \right}$。
      • i=13 部分: 得到 $- (GenDir \cdot GBRatio \cdot c_1) \cdot (GenIner \cdot c_1 \cdot (GenDir \cdot GBRatio \cdot c_1) \ddot{q}{GeAz})$,化简后为 $-GenIner \cdot GBRatio^2 \cdot \ddot{q}{GeAz}$。
    • 与速度导数项的点积: {}^E \boldsymbol{\omega}_{GeAz}^{\text{G}} \cdot (-\overline{\overline{{I}}}^{\text{G}} \cdot \sum_{i=7}^{12} \frac{d}{dt}({}^E \boldsymbol{\omega}_i^{\text{G}}) \dot{q}_i) 这部分得到 $- GenDir \cdot GenIner \cdot GBRatio \cdot c_1 \cdot \left{ \sum_{i=7}^{12} \frac{d}{dt}({}^E \boldsymbol{\omega}_i^{\text{R}}) \dot{q}_i \right}$。
    • 与陀螺力矩项的点积: {}^E \boldsymbol{\omega}_{GeAz}^{\text{G}} \cdot (- {}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}}) 这部分得到 $- GenDir \cdot GBRatio \cdot c_1 \cdot ({}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}})$。

将以上所有部分合并起来,就构成了公式 (16) 中 for r = GeAz 的复杂表达式。


步骤 4: 从 (16) 到 (17) - 第二次化简

这次化简针对公式 (16) 中 r = GeAz 情况下的陀螺力矩项: - GenDir \cdot GBRatio \cdot c_1 \cdot ({}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}})

  1. 由于惯性张量 \overline{\overline{{I}}}^{\text{G}} 只在 c_1 方向有分量,所以 \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}} 的结果是一个与 c_1 平行的向量。我们可以记作 $k \cdot c_1$,其中 k 是一个标量。
  2. 那么叉乘项 {}^E \boldsymbol{\omega}^{\text{G}} \times (\overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}}) 就变成了 ${}^E \boldsymbol{\omega}^{\text{G}} \times (k \cdot c_1)$。
  3. 整个陀螺项就变成了 $... \cdot c_1 \cdot ({}^E \boldsymbol{\omega}^{\text{G}} \times c_1)$。
  4. 再次利用向量混合积的性质:$c_1 \cdot ({}^E \boldsymbol{\omega}^{\text{G}} \times c_1) = {}^E \boldsymbol{\omega}^{\text{G}} \cdot (c_1 \times c_1) = 0$。

因此,r = GeAz 情况下的整个陀螺力矩项为零。从公式 (16) 中去掉这一项,就得到了最终简化后的公式 (17)。

这个化简的物理意义是:对于一个轴对称的转子,陀螺力矩总是垂直于旋转轴的。因此,它在旋转轴方向上没有分量,不会对沿该轴的转动(即发电机自身的加减速)产生影响。 [Timestamp: 2025/11/05 14:58:14]

user: Drivetrain现在在此基础上做简化仅考虑稳态过程加速度为0 [Timestamp: 2025/11/05 16:11:10]

ai: 好的,这是一个非常好的练习,可以帮助我们理解这些复杂方程在简化条件下的物理意义。

当系统处于稳态过程时,我们有两个核心假设:

  1. 所有广义加速度为零: \ddot{q}_i = 0 for all i.
  2. 所有广义速度为常数: \dot{q}_i = \text{constant}.

基于这两个假设,系统的运动方程 [C(q,t)]\ddot{q} = -f(\dot{q},q,t) 急剧简化。由于 $\ddot{q}=0$,左边整个惯性项 [C(q,t)]\ddot{q} 都等于零。因此,方程变为:

-f(\dot{q},q,t) = 0

这意味着在稳态下,所有广义力(主动力、阻尼力、弹性力、陀螺力等)的总和为零。这本质上是一个力矩平衡方程

现在我们逐一分析笔记中各个力在稳态下的简化形式:


各部件广义力的简化

  1. 发电机广义主动力 (Generator)

    • 公式 (5): F_r \Big|_{Gen} = -GBRatio \cdot T^{Gen} (\dots)
    • 这个力不依赖于加速度,只依赖于(恒定的)速度。
    • 简化结果: 保持不变
  2. 高速轴制动器广义主动力 (Brake)

    • 公式 (10): F_{r}\bigr|_{B r a k e} = -G B R a t i o\cdot T^{B r a k e}\left(t\right)
    • 这个力不依赖于加速度。
    • 简化结果: 保持不变。(在典型的稳态发电工况下,T^{Brake} 会是0但我们保留公式形式
  3. 发电机惯性广义力 (Generator Inertia)

    • 这是变化最大的部分。所有与加速度 \ddot{q}_i 相关的项都直接变为零。这意味着质量矩阵 [C(q,t)]|_G 的所有贡献都消失了
    • 我们再看广义力向量 \{-f(\dot{q},q,t)\}|_G (公式 19)。
      • 它包含形如 \frac{d}{dt} ( {}^E \boldsymbol{\omega}_i^{\text{R}} ) \dot{q}_i 的项。因为速度 \dot{q}_i 是常数,所以偏角速度向量 {}^E \boldsymbol{\omega}_i^{\text{R}} 也是常向量,其时间导数 \frac{d}{dt}(...)
      • 它还包含陀螺力矩项 ${}^E \boldsymbol{\omega}^{\text{G}} \times \overline{\overline{{I}}}^{\text{G}} \cdot {}^E \boldsymbol{\omega}^{\text{G}}$。因为角速度 {}^E \boldsymbol{\omega}^{\text{G}} 是恒定的,所以这个陀螺力矩项是存在的,它是一个恒定的力矩
    • 简化结果: 所有与加速度和速度变化相关的惯性力都消失了。唯一剩下的惯性效应是作用在支撑结构DOFs 4-12上的恒定陀螺力矩。对于传动链自身的旋转自由度 $GeAz$,惯性力贡献为
  4. 传动轴弹性 (Elastic Drive)

    • 公式 (21): F_r |_{\text{ElasticDrive}} = -DTTorSpr \cdot q_{DrTr}
    • 在稳态下,传递的扭矩是恒定的,因此轴的扭转角 q_{DrTr} 也是一个恒定的非零值
    • 简化结果: 保持不变
  5. 传动轴阻尼 (Damp Drive)

    • 公式 (22): F_r |_{\text{DampDrive}} = -DTTorDmp \cdot \dot{q}_{DrTr}
    • 在稳态下,轴两端的相对角速度为零,即 $\dot{q}_{DrTr} = 0$。
    • 简化结果: 阻尼力为
  6. 齿轮箱摩擦 (Gearbox Friction)

    • 我们来看摩擦力矩的完整表达式 (公式 31)。所有包含 \ddot{q}_{GeAz}\ddot{q}_i 的项都变为。所有包含 \frac{d}{dt}(...) 的项也都变为
    • 摩擦力矩 T^{\text{GBFric}} 简化为:
      
      T^{\text{GBFric}}_{\text{steady}} = \left[ \text{GBRatio} \cdot T^{\text{Gen}}(\dots) + \text{GBRatio} \cdot T^{\text{Brake}}(t) \right] \cdot \left[ \frac{1}{\text{GBoxEff}^{\text{SIGN(LSShftTq)}}} - 1 \right]
      
    • 简化结果: 摩擦力矩现在只取决于发电机和制动器的负载扭矩,不再与加速度相关。它变成了一个恒定的阻力矩。

最终的稳态平衡方程

现在,我们将所有作用在传动链旋转自由度 (GeAz) 上的广义力相加,并令其等于零。传动链的驱动力是来自叶片的空气动力学扭矩,我们称之为 $T_{aero}$(它作用在低速轴上)。

平衡方程为:


T_{aero} + F_{GeAz}|_{Gen} + F_{GeAz}|_{Brake} + F_{GeAz}|_{GBFric} = 0

代入简化后的表达式:


T_{aero} - GBRatio \cdot T^{Gen} - GBRatio \cdot T^{Brake} - T^{\text{GBFric}}_{\text{steady}} = 0

现在,我们将 T^{\text{GBFric}}_{\text{steady}} 的表达式代入。假设风机在发电,功率从低速轴流向高速轴,所以 SIGN(LSShftTq) 为正,我们用 GBoxEff


T_{aero} - GBRatio \cdot T^{Gen} - GBRatio \cdot T^{Brake} - \left[ GBRatio \cdot T^{Gen} + GBRatio \cdot T^{Brake} \right] \cdot \left( \frac{1}{\text{GBoxEff}} - 1 \right) = 0

整理上式:


T_{aero} = GBRatio \cdot T^{Gen} + GBRatio \cdot T^{Brake} + \frac{GBRatio \cdot (T^{Gen} + T^{Brake})}{\text{GBoxEff}} - GBRatio \cdot (T^{Gen} + T^{Brake})

T_{aero} = \frac{GBRatio \cdot (T^{Gen} + T^{Brake})}{\text{GBoxEff}}

结论与物理意义

在稳态、无加速度的情况下,复杂的动力学方程简化为了一个非常直观的功率平衡扭矩平衡关系:

T_{aero} = \frac{GBRatio}{GBoxEff} \left( T^{Gen} + T^{Brake} \right)

这个公式的物理意义是: 作用在低速轴上的空气动力学扭矩 (T_{aero}),必须等于高速轴上的总负载扭矩(发电机扭矩 T^{Gen} + 制动器扭矩 $T^{Brake}$)经过齿轮箱速比 (GBRatio) 放大,并考虑齿轮箱效率损失 (GBoxEff) 后的等效扭矩。

换句话说,输入的空气动力学功率,等于输出的电功率(和刹车消耗的功率)加上在齿轮箱中损失的功率。所有与惯性、阻尼、动力学耦合相关的复杂项都在稳态下消失了。 [Timestamp: 2025/11/05 16:11:54]

user: FillAugmat从代码中找到drivetrain的部分简化方程求解稳态过程 [Timestamp: 2025/11/05 16:20:35]

ai: Excellent question. Let's bridge the gap between the complex implementation in the FillAugmat code and the theoretical equations in Drivetrain to derive the simplified steady-state solution.

The core idea of a steady-state process is that all accelerations are zero (\ddot{q}=0) and all velocities are constant (\dot{q}=\text{constant}). This dramatically simplifies the system's equation of motion, [C(q,t)]\ddot{q} = -f(\dot{q},q,t), into a simple algebraic force/torque balance equation: -f(\dot{q},q,t) = 0.

In the FillAugmat code, the matrix AugMat represents [C | -f]. The first columns are the mass matrix C, and the last column (p%NAug) is the forcing vector -f. Our goal is to set all terms multiplied by acceleration to zero and see what remains in the forcing vector column.

Let's trace the drivetrain-related terms in the code and apply the steady-state simplification. We are primarily interested in the equations for the generator azimuth (DOF_GeAz) and the drivetrain torsion (DOF_DrTr).

1. Locating and Simplifying Drivetrain Terms in the Code

  1. Generator Torque and HSS Brake Torque

    • Code:
      GBoxTrq = ( u%GenTrq + HSSBrTrq )*ABS(p%GBRatio)
      ...
      AugMat(DOF_GeAz, p%NAug) = ... - GBoxTrq
      
    • Analysis: This term represents the combined generator and brake torque, reflected to the low-speed shaft side. It does not depend on acceleration.
    • Steady-State Simplification: This term remains unchanged. It's a constant torque based on the constant generator speed.
  2. Drivetrain Torsion (Elasticity and Damping)

    • Code: In the IF ( p%DOF_Flag (DOF_DrTr) ) block:
      AugMat(DOF_DrTr, p%NAug) = ... 
                                - p%DTTorSpr*x%QT(DOF_DrTr)  & ! Elasticity
                                - p%DTTorDmp*x%QDT(DOF_DrTr)   ! Damping
      
    • Analysis: This adds the spring and damper forces for the drivetrain torsion DOF. x%QT is the twist angle q_{DrTr}, and x%QDT is the twist rate \dot{q}_{DrTr}.
    • Steady-State Simplification:
      • The elastic term - p%DTTorSpr*x%QT(DOF_DrTr) remains. A constant transmitted torque results in a constant, non-zero twist angle.
      • The damping term - p%DTTorDmp*x%QDT(DOF_DrTr) becomes zero. In steady-state, the rotor and generator spin at constant (but different) speeds. Their relative angular velocity, \dot{q}_{DrTr}, is zero. Therefore, there is no damping torque.
  3. Generator Inertia

    • Code: In the IF ( p%DOF_Flag (DOF_GeAz) ) block:
      ! [C(q,t)]G term added to the mass matrix
      AugMat(DOF_GeAz, DOF_GeAz) = AugMat(DOF_GeAz,DOF_GeAz) + DOT_PRODUCT(...)
      ! {-f(qd,q,t)}G term added to the forcing vector
      AugMat(DOF_GeAz, p%NAug) = AugMat(DOF_GeAz, p%NAug) - DOT_PRODUCT( RtHSdat%AngAccEGt, TmpVec )
      ```    *   **Analysis:** The code adds the generator inertia's contribution to both the mass matrix (terms proportional to $\ddot{q}$) and the forcing vector (terms proportional to $\dot{q}^2$, i.e., gyroscopic effects). `RtHSdat%AngAccEGt` contains these velocity-dependent terms.
      
    • Steady-State Simplification:
      • All terms added to the mass matrix (AugMat(:, 1:N)) are multiplied by \ddot{q}, so their contribution is zero.
      • The RtHSdat%AngAccEGt term contains derivatives of partial velocities. Since all velocities are constant, these derivatives are zero. Therefore, the entire generator inertia contribution to the forcing vector is also zero.
  4. Gearbox Friction

    • Code: At the end of the subroutine:
      GBoxEffFac2 = ( 1.0/RtHSdat%GBoxEffFac - 1.0 )
      ! Term added to the mass matrix (proportional to acceleration)
      AugMat(DOF_GeAz,p%DOFs%SrtPS(I)) = ... + GBoxEffFac2*DOT_PRODUCT(...)
      ! Term added to the forcing vector
      AugMat(   DOF_GeAz,    p%NAug) = ... - GBoxEffFac2*( DOT_PRODUCT( RtHSdat%AngAccEGt, TmpVec ) + GBoxTrq )
      
    • Analysis: This implements the complex friction model where friction depends on both acceleration and the transmitted torque (GBoxTrq).
    • Steady-State Simplification:
      • The term added to the mass matrix is multiplied by \ddot{q}, so its contribution is zero.
      • In the forcing vector term, RtHSdat%AngAccEGt is zero, as established above.
      • The only part that remains is - GBoxEffFac2 * GBoxTrq. This is the friction torque that depends purely on the transmitted load.

2. Assembling the Simplified Steady-State Equation

Now we write the simplified algebraic equations by setting the forcing vector column of AugMat to zero for our DOFs of interest. Let T_{aero} be the aerodynamic torque from the rotor acting on the low-speed shaft.

  1. Equation for DOF_DrTr (Drivetrain Torsion): This DOF balances the torque from the rotor against the torque transmitted through the shaft.

    • AugMat(DOF_DrTr, p%NAug) = 0
    • This simplifies to: T_{aero} - (\text{Elastic Torque}) - (\text{Damping Torque}) = 0
    • T_{aero} - p\%DTTorSpr \cdot x\%QT(DOF\_DrTr) - 0 = 0
    • This tells us that the torque transmitted by the shaft, let's call it T_{shaft}, is equal to the aerodynamic torque: T_{shaft} = T_{aero} = p\%DTTorSpr \cdot x\%QT(DOF\_DrTr).
  2. Equation for DOF_GeAz (Generator Rotation): This DOF balances the torque from the shaft against the generator, brake, and friction torques.

    • AugMat(DOF_GeAz, p%NAug) = 0
    • This simplifies to: T_{shaft} - (\text{Gen/Brake Torque}) - (\text{Inertia Force}) - (\text{Friction Force}) = 0
    • T_{shaft} - GBoxTrq - 0 - ( -GBoxEffFac2 \cdot GBoxTrq ) = 0
    • T_{shaft} - GBoxTrq + GBoxEffFac2 \cdot GBoxTrq = 0
    • T_{shaft} = GBoxTrq \cdot (1 - GBoxEffFac2)
  3. Solving for the Final Equation: Now, let's substitute the definitions of the variables back in. Assume power flows from rotor to generator, so RtHSdat%GBoxEffFac is just p%GBoxEff.

    • GBoxTrq = (u\%GenTrq + HSSBrTrq) \cdot p\%GBRatio
    • GBoxEffFac2 = (\frac{1}{p\%GBoxEff} - 1)

    Substitute these into the DOF_GeAz equation: T_{shaft} = \left[ (u\%GenTrq + HSSBrTrq) \cdot p\%GBRatio \right] \cdot \left( 1 - (\frac{1}{p\%GBoxEff} - 1) \right) T_{shaft} = \left[ (u\%GenTrq + HSSBrTrq) \cdot p\%GBRatio \right] \cdot \left( 2 - \frac{1}{p\%GBoxEff} \right)

    Wait, there seems to be a sign error in my reasoning or the code's comment. Let's re-examine the code for the friction force: AugMat(DOF_GeAz, p%NAug) = ... - GBoxEffFac2*( ... + GBoxTrq ) The total friction force is -GBoxEffFac2 * GBoxTrq. The total generator/brake force is -GBoxTrq. So the equation is: T_{shaft} - GBoxTrq - (GBoxEffFac2 \cdot GBoxTrq) = 0 T_{shaft} = GBoxTrq \cdot (1 + GBoxEffFac2) T_{shaft} = \left[ (u\%GenTrq + HSSBrTrq) \cdot p\%GBRatio \right] \cdot \left( 1 + (\frac{1}{p\%GBoxEff} - 1) \right) T_{shaft} = \left[ (u\%GenTrq + HSSBrTrq) \cdot p\%GBRatio \right] \cdot \left( \frac{1}{p\%GBoxEff} \right)

    Since T_{shaft} = T_{aero}:

    T_{aero} = \frac{p\%GBRatio}{p\%GBoxEff} \left( u\%GenTrq + HSSBrTrq \right)

This final equation is the simplified solution for the steady-state process, derived directly from the code. It perfectly matches the theoretical result: the aerodynamic torque on the low-speed shaft equals the total load torque on the high-speed shaft, scaled by the gear ratio and adjusted for gearbox efficiency losses. [Timestamp: 2025/11/05 16:21:23]

user: FillAugmat基于fillaugmat函数简化出一个fill_steady_augmat函数变量名保持一致求解传动链稳态q [Timestamp: 2025/11/05 16:49:09]

ai: 好的,我们来基于 FillAugmat 函数,简化出一个 fill_steady_augmat 函数用于在稳态加速度为0速度为0条件下构建刚度矩阵 [K] 和外部载荷向量 F_ext,以便后续使用 LU 分解求解广义位移 q

1. 简化原则

  1. 稳态条件: 广义加速度 \ddot{\mathbf{q}} = 0 和广义速度 $\dot{\mathbf{q}} = 0$。
  2. 方程形式: 最终目标是构建并返回 [K]F_ext,以求解线性方程组 [K]q = F_ext
  3. 变量名一致: 尽可能保持原始 FillAugMat 中的变量名。
  4. 忽略动态项:
    • 所有与质量矩阵 [C] 相关的计算(即 AugMat 的前 N 列)将被移除,因为在静态分析中,惯性力为零。
    • 所有与广义加速度 RtHSdat%LinAccESt, RtHSdat%LinAccEOt, RtHSdat%AngAccEGt 相关的项将被视为零。
    • 所有与广义速度 x%QDT 相关的项(阻尼力、科里奥利力、离心力)将被移除,因为在静态分析中,速度为零。
  5. 分离刚度项和外力项:
    • 原始 FillAugMat 中,弹性力项形如 -K*q,并被加到 AugMat 的最后一列 (p%NAug)。在新函数中,K 的系数将被提取出来填充 GlobalStiffnessMatrix
    • 原始 FillAugMat 中,重力、气动力、水动力、刹车力等外部载荷被加到 AugMat 的最后一列 (p%NAug)。在新函数中,这些项将被累加到 ExternalForceVector

2. fill_steady_augmat 子程序伪代码

SUBROUTINE fill_steady_augmat( p, x_static, CoordSys, u_static, HSSBrTrq_static, RtHSdat_static, &
                               GlobalStiffnessMatrix, ExternalForceVector )
!..................................................................................................................................
! This subroutine constructs the global stiffness matrix [K] and the external force vector F_ext
! for a steady-state (static) analysis, where accelerations and velocities are assumed to be zero.
! The output can then be used to solve [K]q = F_ext for static displacements q.
!..................................................................................................................................

      ! Passed variables
   TYPE(ED_ParameterType),       INTENT(IN   )  :: p           !< Parameters
   TYPE(ED_ContinuousStateType), INTENT(IN   )  :: x_static    !< Continuous states (only x_static%QT for displacements is relevant)
   TYPE(ED_CoordSys),            INTENT(IN   )  :: CoordSys    !< The coordinate systems
   TYPE(ED_InputType),           INTENT(IN   )  :: u_static    !< The static aero blade forces/moments
   TYPE(ED_RtHndSide),           INTENT(IN   )  :: RtHSdat_static ! Data from RtHndSid module (assumed to contain static forces/moments and zero accelerations)
   REAL(ReKi),                   INTENT(IN )    :: HSSBrTrq_static ! Static HSS brake torque
   REAL(R8Ki),                   INTENT(OUT)    :: GlobalStiffnessMatrix(:,:) !< The global stiffness matrix [K]
   REAL(R8Ki),                   INTENT(OUT)    :: ExternalForceVector(:)     !< The external force vector F_ext
   
      ! Local variables (keeping original names for consistency, but some will be effectively zero)
   REAL(ReKi)                   :: TmpVec    (3)                                   ! A temporary vector used in various computations.
   REAL(ReKi)                   :: TmpVec1   (3)                                   ! A temporary vector used in various computations.
   REAL(ReKi)                   :: TmpVec3   (3)                                   ! A temporary vector used in various computations.
   REAL(ReKi)                   :: GBoxTrq                                         ! Gearbox torque on the LSS side in N-m (calculated from inputs and parameters).
   REAL(ReKi)                   :: GBoxEffFac2                                     ! A second gearbox efficiency factor = ( 1 / GBoxEff^SgnPrvLSTQ - 1 )

   INTEGER(IntKi)               :: I                                               ! Loops through some or all of the DOFs
   INTEGER(IntKi)               :: J                                               ! Counter for elements
   INTEGER(IntKi)               :: K                                               ! Counter for blades
   INTEGER(IntKi)               :: L                                               ! Generic index

   ! Initialize the output matrices:
   GlobalStiffnessMatrix = 0.0
   ExternalForceVector   = 0.0

   ! Calculate static gearbox torque (HSSBrTrq_static is assumed to be a static value)
   GBoxTrq = ( u_static%GenTrq + HSSBrTrq_static ) * ABS(p%GBRatio) 
   
   ! NOTE: For this static function, we assume that all acceleration-related fields
   !       in RtHSdat_static (e.g., LinAccESt, LinAccEOt, AngAccEGt) are already zero.
   !       Also, force/moment fields (e.g., FSAero, MMAero, FTHydrot, MFHydrot, FrcZAllt, MomXAllt, FrcONcRtt, MomBNcRtt, MomNGnRtt)
   !       are assumed to represent only their static (non-inertial, non-damping) components.

   ! Loop through all blades
   DO K = 1,p%NumBl 
      ! Blade tip forces (only static aero and gravity contributions)
      ! Original: TmpVec1 = RtHSdat%FSTipDrag(:,K) - p%TipMass(K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,p%TipNode) )
      TmpVec1 = RtHSdat_static%FSTipDrag(:,K) - p%TipMass(K)*( p%Gravity*CoordSys%z2 ) ! LinAccESt is 0
      DO I = 1,p%DOFs%NPSBE(K)
            ExternalForceVector(p%DOFs%PSBE(K,I)) = ExternalForceVector(p%DOFs%PSBE(K,I)) + &
                                                     DOT_PRODUCT( RtHSdat_static%PLinVelES(K,p%TipNode,p%DOFs%PSBE(K,I),0,:), TmpVec1 )
      ENDDO

      ! Loop through blade nodes / elements
      DO J = 1,p%BldNodes 
         ! Blade element forces (static aero, gravity, hydro)
         ! Original: TmpVec1 = RtHSdat%FSAero(:,K,J)*p%DRNodes(J) - p%BElmntMass(J,K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,J) )
         TmpVec1 = ( RtHSdat_static%FSAero(:,K,J)*p%DRNodes(J) ) - p%BElmntMass(J,K)*( p%Gravity*CoordSys%z2 ) ! LinAccESt is 0
         TmpVec3 = ( RtHSdat_static%MMAero(:,K,J)*p%DRNodes(J) )
         DO I = 1,p%DOFs%NPSBE(K)
               ExternalForceVector(p%DOFs%PSBE(K,I)) = ExternalForceVector(p%DOFs%PSBE(K,I)) + &
                                                         DOT_PRODUCT( RtHSdat_static%PLinVelES(K,J,p%DOFs%PSBE(K,I),0,:), TmpVec1 ) + &
                                                         DOT_PRODUCT( RtHSdat_static%PAngVelEM(K,J,p%DOFs%PSBE(K,I),0,:), TmpVec3 )
         ENDDO
      ENDDO ! J - Blade nodes / elements      
      
      ! Blade elasticity forces (damping forces are zero in static analysis)
      IF ( p%DOF_Flag(DOF_BF(K,1)) )  THEN
         GlobalStiffnessMatrix(DOF_BF(K,1),DOF_BF(K,1)) = GlobalStiffnessMatrix(DOF_BF(K,1),DOF_BF(K,1)) + p%KBF(K,1,1)
         GlobalStiffnessMatrix(DOF_BF(K,1),DOF_BF(K,2)) = GlobalStiffnessMatrix(DOF_BF(K,1),DOF_BF(K,2)) + p%KBF(K,1,2)
      ENDIF
      IF ( p%DOF_Flag(DOF_BF(K,2)) )  THEN
         GlobalStiffnessMatrix(DOF_BF(K,2),DOF_BF(K,1)) = GlobalStiffnessMatrix(DOF_BF(K,2),DOF_BF(K,1)) + p%KBF(K,2,1)
         GlobalStiffnessMatrix(DOF_BF(K,2),DOF_BF(K,2)) = GlobalStiffnessMatrix(DOF_BF(K,2),DOF_BF(K,2)) + p%KBF(K,2,2)
      ENDIF
      IF ( p%DOF_Flag(DOF_BE(K,1)) )  THEN
         GlobalStiffnessMatrix(DOF_BE(K,1),DOF_BE(K,1)) = GlobalStiffnessMatrix(DOF_BE(K,1),DOF_BE(K,1)) + p%KBE(K,1,1)
      ENDIF
   END DO ! K - Blades
         
   ! Yaw bearing gravity force
   ! Original: TmpVec1 = -p%YawBrMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEOt )
   TmpVec1 = -p%YawBrMass*( p%Gravity*CoordSys%z2 ) ! LinAccEOt is 0
   DO I = 1,p%DOFs%NPTTE
         ExternalForceVector(p%DOFs%PTTE(I)) = ExternalForceVector(p%DOFs%PTTE(I)) + &
                                                DOT_PRODUCT( RtHSdat_static%PLinVelEO(p%DOFs%PTTE(I),0,:), TmpVec1 )
   ENDDO
   
   ! Loop through tower nodes / elements
   DO J = 1,p%TwrNodes
      ! Tower element forces (static hydro, gravity)
      ! Original: TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*abs(p%DHNodes(J)) - p%TElmntMass(J)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccETt(:,J) )
      TmpVec1 = ( RtHSdat_static%FTHydrot(:,J) )*abs(p%DHNodes(J)) - p%TElmntMass(J)*( p%Gravity*CoordSys%z2 ) ! LinAccETt is 0
      TmpVec3 = ( RtHSdat_static%MFHydrot(:,J) )*abs(p%DHNodes(J))
      DO I = 1,p%DOFs%NPTTE
            ExternalForceVector(p%DOFs%PTTE(I)) = ExternalForceVector(p%DOFs%PTTE(I)) + &
                                                  DOT_PRODUCT( RtHSdat_static%PLinVelET(J,p%DOFs%PTTE(I),0,:), TmpVec1 ) + &
                                                  DOT_PRODUCT( RtHSdat_static%PAngVelEF(J,p%DOFs%PTTE(I),0,:), TmpVec3 )
      ENDDO
   ENDDO ! J - Tower nodes / elements   
   
   ! Tower elasticity forces (damping forces are zero in static analysis)
   IF ( p%DOF_Flag(DOF_TFA1) )  THEN
      GlobalStiffnessMatrix(DOF_TFA1,DOF_TFA1) = GlobalStiffnessMatrix(DOF_TFA1,DOF_TFA1) + p%KTFA(1,1)
      GlobalStiffnessMatrix(DOF_TFA1,DOF_TFA2) = GlobalStiffnessMatrix(DOF_TFA1,DOF_TFA2) + p%KTFA(1,2)
   ENDIF
   IF ( p%DOF_Flag(DOF_TSS1) )  THEN
      GlobalStiffnessMatrix(DOF_TSS1,DOF_TSS1) = GlobalStiffnessMatrix(DOF_TSS1,DOF_TSS1) + p%KTSS(1,1)
      GlobalStiffnessMatrix(DOF_TSS1,DOF_TSS2) = GlobalStiffnessMatrix(DOF_TSS1,DOF_TSS2) + p%KTSS(1,2)
   ENDIF
   IF ( p%DOF_Flag(DOF_TFA2) )  THEN
      GlobalStiffnessMatrix(DOF_TFA2,DOF_TFA1) = GlobalStiffnessMatrix(DOF_TFA2,DOF_TFA1) + p%KTFA(2,1)
      GlobalStiffnessMatrix(DOF_TFA2,DOF_TFA2) = GlobalStiffnessMatrix(DOF_TFA2,DOF_TFA2) + p%KTFA(2,2)
   ENDIF
   IF ( p%DOF_Flag(DOF_TSS2) )  THEN
      GlobalStiffnessMatrix(DOF_TSS2,DOF_TSS1) = GlobalStiffnessMatrix(DOF_TSS2,DOF_TSS1) + p%KTSS(2,1)
      GlobalStiffnessMatrix(DOF_TSS2,DOF_TSS2) = GlobalStiffnessMatrix(DOF_TSS2,DOF_TSS2) + p%KTSS(2,2)
   ENDIF
   
   ! Other DOF forces (only static components)
   ! Mass matrix contributions from partial loads are removed.
   ! Coriolis/centrifugal terms are removed.
   IF ( p%DOF_Flag (DOF_Sg  ) )  THEN
         ExternalForceVector(DOF_Sg  ) = ExternalForceVector(DOF_Sg  ) + DOT_PRODUCT( RtHSdat_static%PLinVelEZ(DOF_Sg ,0,:), RtHSdat_static%FrcZAllt )
   ENDIF
   IF ( p%DOF_Flag (DOF_Sw  ) )  THEN
         ExternalForceVector(DOF_Sw  ) = ExternalForceVector(DOF_Sw  ) + DOT_PRODUCT( RtHSdat_static%PLinVelEZ(DOF_Sw ,0,:), RtHSdat_static%FrcZAllt )
   ENDIF
   IF ( p%DOF_Flag (DOF_Hv  ) )  THEN
         ExternalForceVector(DOF_Hv  ) = ExternalForceVector(DOF_Hv  ) + DOT_PRODUCT( RtHSdat_static%PLinVelEZ(DOF_Hv ,0,:), RtHSdat_static%FrcZAllt )
   ENDIF
   IF ( p%DOF_Flag (DOF_R   ) )  THEN
         ExternalForceVector(DOF_R   ) = ExternalForceVector(DOF_R   ) + DOT_PRODUCT( RtHSdat_static%PAngVelEX(DOF_R  ,0,:), RtHSdat_static%MomXAllt )
   ENDIF
   IF ( p%DOF_Flag (DOF_P   ) )  THEN
         ExternalForceVector(DOF_P   ) = ExternalForceVector(DOF_P   ) + DOT_PRODUCT( RtHSdat_static%PAngVelEX(DOF_P  ,0,:), RtHSdat_static%MomXAllt )
   ENDIF
   IF ( p%DOF_Flag (DOF_Y   ) )  THEN
         ExternalForceVector(DOF_Y   ) = ExternalForceVector(DOF_Y   ) + DOT_PRODUCT( RtHSdat_static%PAngVelEX(DOF_Y  ,0,:), RtHSdat_static%MomXAllt ) + u_static%YawMom
   ENDIF

   ! Coupling terms for TFA/TSS DOFs (only static force contributions)
   IF ( p%DOF_Flag (DOF_TFA1) )  THEN
         ExternalForceVector(DOF_TFA1) = ExternalForceVector(DOF_TFA1) + &
                                          DOT_PRODUCT( RtHSdat_static%PLinVelEO(DOF_TFA1,0,:), RtHSdat_static%FrcONcRtt  ) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEB(DOF_TFA1,0,:), RtHSdat_static%MomBNcRtt  )
   ENDIF
   IF ( p%DOF_Flag (DOF_TSS1) )  THEN
         ExternalForceVector(DOF_TSS1) = ExternalForceVector(DOF_TSS1) + &
                                          DOT_PRODUCT( RtHSdat_static%PLinVelEO(DOF_TSS1,0,:), RtHSdat_static%FrcONcRtt  ) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEB(DOF_TSS1,0,:), RtHSdat_static%MomBNcRtt  )
   ENDIF
   IF ( p%DOF_Flag (DOF_TFA2) )  THEN
         ExternalForceVector(DOF_TFA2) = ExternalForceVector(DOF_TFA2) + &
                                          DOT_PRODUCT( RtHSdat_static%PLinVelEO(DOF_TFA2,0,:), RtHSdat_static%FrcONcRtt  ) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEB(DOF_TFA2,0,:), RtHSdat_static%MomBNcRtt  )
   ENDIF
   IF ( p%DOF_Flag (DOF_TSS2) )  THEN
         ExternalForceVector(DOF_TSS2) = ExternalForceVector(DOF_TSS2) + &
                                          DOT_PRODUCT( RtHSdat_static%PLinVelEO(DOF_TSS2,0,:), RtHSdat_static%FrcONcRtt  ) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEB(DOF_TSS2,0,:), RtHSdat_static%MomBNcRtt  )
   ENDIF
   
   ! Yaw, RFrl, GeAz, DrTr, TFrl, Teet DOFs (only static force/moment contributions)
   ! TmpVec related to generator inertia is effectively zero for static.
   IF ( p%DOF_Flag (DOF_GeAz) )  THEN
         ExternalForceVector(DOF_GeAz) = ExternalForceVector(DOF_GeAz) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEL(DOF_GeAz,0,:), RtHSdat_static%MomLPRott ) - GBoxTrq
   ENDIF
   IF ( p%DOF_Flag (DOF_DrTr) )  THEN
         ! The elastic force -p%DTTorSpr*x_static%QT(DOF_DrTr) is moved to the stiffness matrix
         ExternalForceVector(DOF_DrTr) = ExternalForceVector(DOF_DrTr) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEL(DOF_DrTr,0,:), RtHSdat_static%MomLPRott )
         GlobalStiffnessMatrix(DOF_DrTr, DOF_DrTr) = GlobalStiffnessMatrix(DOF_DrTr, DOF_DrTr) + p%DTTorSpr
   ENDIF
   IF ( p%DOF_Flag (DOF_TFrl) )  THEN
         ExternalForceVector(DOF_TFrl) = ExternalForceVector(DOF_TFrl) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEA(DOF_TFrl,0,:), RtHSdat_static%MomNTailt ) + RtHSdat_static%TFrlMom
   ENDIF
   IF ( ( p%NumBl == 2 ) ) THEN 
      IF ( p%DOF_Flag(DOF_Teet) )  THEN
         ExternalForceVector(DOF_Teet) = ExternalForceVector(DOF_Teet) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEH(DOF_Teet,0,:), RtHSdat_static%MomLPRott ) + RtHSdat_static%TeetMom
      ENDIF
   ENDIF

   ! Fill in the upper triangle of the stiffness matrix (it should be symmetric)
   DO L = 2,p%DOFs%NActvDOF
      DO I = 1,L-1
         GlobalStiffnessMatrix(p%DOFs%SrtPS(I),p%DOFs%SrtPS(L)) = GlobalStiffnessMatrix(p%DOFs%SrtPS(L),p%DOFs%SrtPS(I))
      ENDDO
   ENDDO

   ! Gearbox friction (non-conservative, contributes to F_ext)
   GBoxEffFac2 = ( 1.0/RtHSdat_static%GBoxEffFac - 1.0 )
   ExternalForceVector(DOF_GeAz) = ExternalForceVector(DOF_GeAz) - GBoxEffFac2 * GBoxTrq ! AngAccEGt is 0

END SUBROUTINE fill_steady_augmat

3. 使用 LU 分解求解 q (在主程序中调用)

在你的主程序中,调用 fill_steady_augmat 后,你需要一个线性代数库(如 LAPACK来执行 LU 分解并求解 [K]q = F_ext

PROGRAM StaticAnalysis
  USE ED_Types ! Assuming ED_Types contains definitions for ED_ParameterType, ED_ContinuousStateType, etc.
  ! USE LAPACK_MODULE ! Assuming you have a LAPACK interface module

  IMPLICIT NONE

  ! Declare variables (matching the subroutine interface)
  TYPE(ED_ParameterType)        :: p
  TYPE(ED_ContinuousStateType)  :: x_static
  TYPE(ED_CoordSys)             :: CoordSys
  TYPE(ED_InputType)            :: u_static
  TYPE(ED_RtHndSide)            :: RtHSdat_static
  REAL(ReKi)                    :: HSSBrTrq_static
  
  INTEGER(IntKi)                :: N_DOF
  REAL(R8Ki), ALLOCATABLE       :: GlobalStiffnessMatrix(:,:)
  REAL(R8Ki), ALLOCATABLE       :: ExternalForceVector(:)
  REAL(R8Ki), ALLOCATABLE       :: q_solution(:)
  INTEGER(IntKi), ALLOCATABLE   :: ipiv(:)
  INTEGER(IntKi)                :: info

  ! --- 1. 初始化参数和静态状态 ---
  ! 这一步需要根据你的具体风机模型和稳态工况来填充
  ! 例如:
  ! CALL Init_Parameters(p)
  ! CALL Init_StaticStates(x_static) ! x_static%QT 应该包含初始猜测的位移x_static%QDT 应该为0
  ! CALL Init_CoordSys(CoordSys)
  ! CALL Init_StaticInputs(u_static) ! u_static%GenTrq 等应为稳态值
  ! HSSBrTrq_static = 0.0_ReKi ! 或其他稳态刹车力
  ! CALL Init_RtHSdat_Static(RtHSdat_static, p, x_static, CoordSys, u_static) 
  !    ! 这个函数需要你自己实现,确保 RtHSdat_static 中的加速度项为0力/力矩项为稳态值

  ! 获取自由度数量
  N_DOF = p%DOFs%NActvDOF ! 假设 p%DOFs%NActvDOF 包含了所有激活的自由度数量

  ! 分配矩阵和向量
  ALLOCATE(GlobalStiffnessMatrix(N_DOF, N_DOF))
  ALLOCATE(ExternalForceVector(N_DOF))
  ALLOCATE(q_solution(N_DOF))
  ALLOCATE(ipiv(N_DOF))

  ! --- 2. 调用 fill_steady_augmat 构建 [K] 和 F_ext ---
  CALL fill_steady_augmat( p, x_static, CoordSys, u_static, HSSBrTrq_static, RtHSdat_static, &
                           GlobalStiffnessMatrix, ExternalForceVector )

  ! --- 3. 求解线性方程组 [K]q = F_ext ---
  ! LAPACK 的 DGESV 子程序会修改 GlobalStiffnessMatrix (存储 LU 分解结果) 和 ExternalForceVector (存储解)
  q_solution = ExternalForceVector ! 将 F_ext 复制到 q_solution因为 DGESV 会覆盖它

  ! 调用 LAPACK 的 DGESV 子程序
  ! N: 矩阵的阶数
  ! NRHS: 右端向量的数量 (这里是1)
  ! A: 输入矩阵 [K],输出为 LU 分解结果
  ! LDA: 矩阵 A 的第一维大小
  ! IPIV: 存储行交换信息的向量
  ! B: 输入向量 F_ext输出为解 q
  ! LDB: 矩阵 B 的第一维大小 (这里是 N_DOF)
  ! INFO: 错误信息 (0表示成功)
  CALL DGESV( N_DOF, 1, GlobalStiffnessMatrix, N_DOF, ipiv, q_solution, N_DOF, info )

  IF ( info == 0 ) THEN
    PRINT *, 'Static displacements (q_solution):'
    PRINT *, q_solution
    ! 可以将 q_solution 更新回 x_static%QT以便后续使用
    ! x_static%QT = q_solution
  ELSE
    PRINT *, 'Error solving linear system: INFO = ', info
  END IF

  ! 释放内存
  DEALLOCATE(GlobalStiffnessMatrix)
  DEALLOCATE(ExternalForceVector)
  DEALLOCATE(q_solution)
  DEALLOCATE(ipiv)

END PROGRAM StaticAnalysis

重要提示:

  • Init_RtHSdat_Static 函数: 这个函数是关键。在实际的 FAST 仿真中,RtHSdat 是由 RtHndSid 模块在每个时间步计算的。对于静态分析,你需要确保 RtHSdat_static 中的所有加速度相关项(如 LinAccESt, LinAccEOt, AngAccEGt)都被设置为零。同时,所有力/力矩相关项(如 FSAero, MMAero, FTHydrot, MFHydrot, FrcZAllt, MomXAllt, FrcONcRtt, MomBNcRtt, MomNGnRtt)必须准确反映稳态的外部载荷(例如,恒定风速下的气动力,或静水中的水动力)。
  • x_static%QT: 在调用 DGESV 之前,x_static%QT 应该包含一个初始猜测的位移向量。如果 [K] 是非线性的(例如,包含几何刚度效应),你可能需要一个迭代过程(如牛顿-拉普森法)来求解,每次迭代都更新 x_static%QT 并重新构建 [K]F_ext。这里提供的代码是针对线性 [K] 的直接求解。
  • LAPACK 接口: DGESV 是 LAPACK 库中的一个标准双精度通用矩阵求解器。你需要确保你的 Fortran 编译器能够链接到 LAPACK 库,并且 DGESV 的接口声明正确。
  • DOF 索引: p%DOFs%PSBE, p%DOFs%PTTE, p%DOFs%SrtPS 等数组用于将物理自由度映射到矩阵的行/列索引。这些在 FillAugMat 中已经定义,并应在 fill_steady_augmat 中保持一致。

通过这些步骤,你就可以将原始的动态 FillAugmat 函数转化为一个高效的静态分析工具,并利用 LU 分解来求解塔架在稳态条件下的变形。 [Timestamp: 2025/11/05 16:50:27]

user: 解释在代码中如何求解的p%DOF_Flag(DOF_DrTr) p%DOF_Flag(DOF_GeAz)都为True [Timestamp: 2025/11/05 16:57:38]

ai: Of course. Let's break down how the equations for the drivetrain degrees of freedom, DOF_DrTr (Drivetrain Torsion) and DOF_GeAz (Generator Azimuth), are constructed and solved within the FillAugmat subroutine.

The overall goal of FillAugmat is to build the system of linear equations:

[C]\ddot{\mathbf{q}} = \mathbf{F}

where [C] is the mass matrix and F is the forcing vector (represented as {-f} in the theory). The code builds an augmented matrix AugMat of the form [ [C] | F ]. After this subroutine finishes, an external solver (typically using LU decomposition) will solve for the vector of accelerations, \ddot{\mathbf{q}}.

When both p%DOF_Flag(DOF_DrTr) and p%DOF_Flag(DOF_GeAz) are True, it means we are using a two-mass drivetrain model. Here's how the equations for these two specific DOFs are assembled.


1. Equation for DOF_DrTr (Drivetrain Torsion)

This degree of freedom represents the twist angle between the rotor/hub (low-speed side) and the generator (high-speed side, reflected to low-speed). Its equation is a balance of torques acting on the rotor relative to the generator.

The relevant code block is:

IF ( p%DOF_Flag (DOF_DrTr) )  THEN
   ! ... Mass matrix terms ...
   AugMat(p%DOFs%SrtPS(I),DOF_DrTr) = -DOT_PRODUCT( RtHSdat%PAngVelEL(DOF_DrTr,0,:), RtHSdat%PMomLPRot(:,p%DOFs%SrtPS(I)) )

   ! ... Forcing vector term ...
   AugMat(DOF_DrTr, p%NAug) =  DOT_PRODUCT( RtHSdat%PAngVelEL(DOF_DrTr,0,:), RtHSdat%MomLPRott ) &
                               -  p%DTTorSpr*x%QT (DOF_DrTr)                                    &
                               -  p%DTTorDmp*x%QDT(DOF_DrTr)
ENDIF

Let's break down the forcing vector AugMat(DOF_DrTr, p%NAug):

  1. DOT_PRODUCT( RtHSdat%PAngVelEL(DOF_DrTr,0,:), RtHSdat%MomLPRott ): This is the driving torque.

    • RtHSdat%MomLPRott: Represents the total moment (torque) acting on the low-speed shaft from the rotor. This includes aerodynamic torque, gravitational moments on the blades, and inertial (gyroscopic) moments from the blades' motion. It's the net torque that the wind and blades are providing to the drivetrain.
    • RtHSdat%PAngVelEL(DOF_DrTr,0,:): This is the partial angular velocity for the DrTr DOF.
    • The dot product projects the total rotor torque onto the drivetrain torsion DOF axis, giving the generalized force that drives this motion.
  2. - p%DTTorSpr*x%QT(DOF_DrTr): This is the restoring spring torque.

    • p%DTTorSpr: The torsional stiffness of the drivetrain shaft.
    • x%QT(DOF_DrTr): The current twist angle, q_{DrTr}.
    • This term represents Hooke's Law for torsion. The more the shaft twists, the larger the restoring torque it exerts, trying to return to its untwisted state.
  3. - p%DTTorDmp*x%QDT(DOF_DrTr): This is the damping torque.

    • p%DTTorDmp: The torsional damping coefficient of the drivetrain.
    • x%QDT(DOF_DrTr): The current twist rate, \dot{q}_{DrTr}.
    • This term represents energy dissipation in the shaft. It creates a torque that opposes the relative rotational speed between the two ends of the shaft.

In essence, the equation for DOF_DrTr being built here is:

(I_{rotor} + ...)\ddot{q}_{DrTr} + ... = T_{aero\_etc} - K_{shaft} \cdot q_{DrTr} - D_{shaft} \cdot \dot{q}_{DrTr}

2. Equation for DOF_GeAz (Generator Azimuth)

This degree of freedom represents the absolute rotation of the generator. Its equation is a balance of torques acting on the generator.

This is more complex as it's assembled from three different parts of the code.

a. Main Driving and Load Torques

IF ( p%DOF_Flag (DOF_GeAz) )  THEN
   ! ... Mass matrix terms ...
   AugMat(DOF_GeAz, p%NAug) =  DOT_PRODUCT( RtHSdat%PAngVelEL(DOF_GeAz,0,:), RtHSdat%MomLPRott ) &
                               -  GBoxTrq
ENDIF
  1. DOT_PRODUCT( RtHSdat%PAngVelEL(DOF_GeAz,0,:), RtHSdat%MomLPRott ): This is the torque transmitted through the shaft to the generator side. It's the same physical torque from the rotor, but now it's acting as the input to the generator.
  2. - GBoxTrq: This is the primary load torque. GBoxTrq is calculated at the top of the subroutine as ( u%GenTrq + HSSBrTrq )*ABS(p%GBRatio). It represents the sum of the generator's electromagnetic torque and the high-speed shaft brake torque, both reflected back to the low-speed shaft side.

b. Generator Inertia

! ... inside the IF block for DOF_GeAz ...
! Mass matrix term for generator's own inertia
AugMat(DOF_GeAz, DOF_GeAz) = AugMat(DOF_GeAz,DOF_GeAz) + DOT_PRODUCT( RtHSdat%PAngVelEG(DOF_GeAz,0,:), TmpVec )
! Forcing vector term for generator's gyroscopic effects
AugMat(DOF_GeAz, p%NAug) = AugMat(DOF_GeAz, p%NAug) - DOT_PRODUCT( RtHSdat%AngAccEGt, TmpVec )```
*   The first line adds the generator's own rotational inertia (`p%GenIner` scaled by `GBRatio^2`) to the diagonal of the mass matrix. This is the $I_{gen} \ddot{q}_{GeAz}$ term.
*   The second line adds the gyroscopic forces from the generator's inertia to the forcing vector. This term is proportional to $\dot{q}^2$ and is non-zero if the generator is rotating and the nacelle is pitching or yawing.

#### c. Gearbox Friction
```fortran
! ... at the end of the subroutine ...
GBoxEffFac2 = ( 1.0/RtHSdat%GBoxEffFac - 1.0 )
! ...
AugMat(DOF_GeAz, p%NAug) = AugMat(DOF_GeAz, p%NAug) &
                         - GBoxEffFac2*( DOT_PRODUCT( RtHSdat%AngAccEGt, TmpVec ) + GBoxTrq )

This adds the friction torque to the forcing vector. The friction is modeled as being proportional to the sum of the torque required to accelerate the generator (DOT_PRODUCT(...)) and the load torque (GBoxTrq). This is a resistive torque that opposes the motion.

Combining these parts, the equation for DOF_GeAz is essentially:

(I_{gen} + I_{friction\_apparent})\ddot{q}_{GeAz} + ... = T_{shaft} - T_{load} - T_{friction} - T_{gyro}

3. The Solution Process

  1. Build the System: FillAugmat completes its run, having filled all rows and columns of the AugMat matrix for all active DOFs, including the two we just analyzed. At this point, we have a complete system of linear equations [C]ddot_q = F.

  2. Solve for Accelerations: A separate routine outside of FillAugmat takes the completed AugMat and solves it for the vector of unknown accelerations, \ddot{\mathbf{q}}. This is typically done using LU decomposition, which is an efficient method for solving Ax=b.

  3. Time Integration: Once the accelerations \ddot{\mathbf{q}} are known at the current time step, a numerical integrator (e.g., Runge-Kutta, Adams-Bashforth-Moulton) uses them to advance the states (displacements q and velocities q_dot) to the next time step.

This cycle—calculate forces (RtHndSid), build the matrix (FillAugmat), solve for accelerations (LU solver), and integrate in time—repeats for the entire duration of the simulation. [Timestamp: 2025/11/05 16:58:18]

user: FillAugmat基于fillaugmat函数简化出一个fill_steady_augmat函数变量名保持一致求解传动链稳态q解释在fill_steady_augmat函数中如何求解的p%DOF_Flag(DOF_DrTr) p%DOF_Flag(DOF_GeAz)都为True [Timestamp: 2025/11/06 11:29:29]

ai: 好的,我们来详细解释在 fill_steady_augmat 子程序中,当 p%DOF_Flag(DOF_DrTr)p%DOF_Flag(DOF_GeAz) 都为 True 时,传动链的稳态方程是如何构建的,以及 q 是如何被求解的。

稳态分析的核心假设

在稳态(静态)分析中,我们有以下关键假设:

  1. 所有广义加速度为零: \ddot{\mathbf{q}} = 0
  2. 所有广义速度为零: \dot{\mathbf{q}} = 0

这些假设将原始的动力学方程 [M]ddot_q + [D]dot_q + [K]q = F_ext 简化为纯粹的静力学平衡方程:

[K]\mathbf{q} = \mathbf{F}_{ext}

其中,[K] 是全局刚度矩阵,q 是广义位移向量,F_ext 是外部载荷向量。fill_steady_augmat 的任务就是构建 [K]F_ext

1. DOF_DrTr (传动链扭转自由度) 的方程构建

DOF_DrTr 代表传动轴的扭转变形。在稳态下,传动轴会扭转以传递转子和发电机之间的净扭矩。

相关代码块:

   IF ( p%DOF_Flag (DOF_DrTr) )  THEN
         ! 外部载荷向量 F_ext 的贡献
         ExternalForceVector(DOF_DrTr) = ExternalForceVector(DOF_DrTr) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEL(DOF_DrTr,0,:), RtHSdat_static%MomLPRott )
         ! 刚度矩阵 [K] 的贡献
         GlobalStiffnessMatrix(DOF_DrTr, DOF_DrTr) = GlobalStiffnessMatrix(DOF_DrTr, DOF_DrTr) + p%DTTorSpr
   ENDIF

解释:

  1. 刚度矩阵 [K] 的贡献:

    • GlobalStiffnessMatrix(DOF_DrTr, DOF_DrTr) = GlobalStiffnessMatrix(DOF_DrTr, DOF_DrTr) + p%DTTorSpr
    • 这行代码将传动轴的扭转刚度 p%DTTorSpr 添加到 GlobalStiffnessMatrixDOF_DrTr 对应的对角线元素上。
    • 这代表了传动轴的弹性恢复力矩,即 $K_{DrTr} \cdot q_{DrTr}$。
  2. 外部载荷向量 F_ext 的贡献:

    • DOT_PRODUCT( RtHSdat_static%PAngVelEL(DOF_DrTr,0,:), RtHSdat_static%MomLPRott )
    • RtHSdat_static%MomLPRott: 代表作用在低速轴上的净静态扭矩,这包括气动扭矩、叶片重力矩以及其他来自转子的静态力矩。
    • RtHSdat_static%PAngVelEL(DOF_DrTr,0,:): 这是 DOF_DrTr 的偏角速度向量。
    • 点积运算将转子扭矩投影到 DOF_DrTr 轴上,得到驱动传动轴扭转的广义力(扭矩)。这个扭矩被添加到 ExternalForceVector(DOF_DrTr) 中。

稳态下被忽略的项:

  • 质量矩阵项(与 \ddot{q}_{DrTr} 相关)被忽略。
  • 阻尼项 - p%DTTorDmp*x_static%QDT(DOF_DrTr) 被忽略,因为稳态下相对扭转速度 x_static%QDT(DOF_DrTr) 为零。

DOF_DrTr 的稳态方程:[K]q = F_ext 系统中,DOF_DrTr 对应的行将是:


p\%DTTorSpr \cdot q_{DrTr} = \text{DOT_PRODUCT}( \text{RtHSdat_static%PAngVelEL(DOFDrTr,0,:)}, \text{RtHSdatstatic%MomLPRott} ) 

这表示传动轴的弹性扭矩与来自转子的净静态扭矩相平衡。


2. DOF_GeAz (发电机方位角自由度) 的方程构建

DOF_GeAz 代表发电机的绝对旋转位置。在稳态下,发电机以恒定速度旋转(或静止),作用在其上的所有扭矩必须平衡。

相关代码块:

a. 主要驱动和负载扭矩:

   IF ( p%DOF_Flag (DOF_GeAz) )  THEN
         ExternalForceVector(DOF_GeAz) = ExternalForceVector(DOF_GeAz) + &
                                          DOT_PRODUCT( RtHSdat_static%PAngVelEL(DOF_GeAz,0,:), RtHSdat_static%MomLPRott ) - GBoxTrq
   ENDIF
  1. DOT_PRODUCT( RtHSdat_static%PAngVelEL(DOF_GeAz,0,:), RtHSdat_static%MomLPRott ):

    • 这与 DOF_DrTr 中的驱动扭矩来源相同,代表从转子通过传动链传递到发电机侧的净静态扭矩。
  2. - GBoxTrq:

    • GBoxTrq 在子程序开头计算为 ( u_static%GenTrq + HSSBrTrq_static ) * ABS(p%GBRatio)
    • 这代表了发电机电磁扭矩 (u_static%GenTrq) 和高速轴制动器扭矩 (HSSBrTrq_static) 的总和,并折算到低速轴侧。这是一个负载扭矩,因此是负号。

b. 发电机惯性 (简化): 在原始的 FillAugMat 中,发电机惯性对质量矩阵和力向量都有贡献。但在 fill_steady_augmat 中:

  • 质量矩阵项被忽略。
  • 力向量中的陀螺效应项(与 RtHSdat%AngAccEGt 相关)被忽略,因为 RtHSdat_static%AngAccEGt 在稳态下为零。

c. 齿轮箱摩擦:

   ! ... 在子程序末尾 ...
   GBoxEffFac2 = ( 1.0/RtHSdat_static%GBoxEffFac - 1.0 )
   ExternalForceVector(DOF_GeAz) = ExternalForceVector(DOF_GeAz) - GBoxEffFac2 * GBoxTrq ! AngAccEGt is 0
  1. GBoxEffFac2 = ( 1.0/RtHSdat_static%GBoxEffFac - 1.0 ): 计算齿轮箱效率因子。
  2. - GBoxEffFac2 * GBoxTrq: 这代表齿轮箱内的摩擦扭矩。它与传递的负载扭矩 GBoxTrq 和效率损失因子成正比。这是一个阻力矩,因此是负号。

DOF_GeAz 的稳态方程:[K]q = F_ext 系统中,DOF_GeAz 对应的行将是:

0 = \text{DOT_PRODUCT}( \text{RtHSdat_static%PAngVelEL(DOF_GeAz,0,:)}, \text{RtHSdat_static%MomLPRott} ) - GBoxTrq - GBoxEffFac2 \cdot GBoxTrq

整理后:
\text{DOT_PRODUCT}( \text{RtHSdat_static%PAngVelEL(DOF_GeAz,0,:)}, \text{RtHSdat_static%MomLPRott} ) = GBoxTrq \cdot (1 + GBoxEffFac2) 

 \text{DOT_PRODUCT}( \text{RtHSdat_static%PAngVelEL(DOF_GeAz,0,:)}, \text{RtHSdat_static%MomLPRott} ) = GBoxTrq \cdot \left( \frac{1}{\text{RtHSdat_static%GBoxEffFac}} \right) 
 
这个方程表示从转子传递到发电机侧的输入扭矩,必须平衡发电机/制动器负载扭矩加上齿轮箱的摩擦损失。

**`DOF_GeAz` 对刚度矩阵 `[K]` 的贡献:**
在 `fill_steady_augmat` 中,`DOF_GeAz` **没有显式地向 `GlobalStiffnessMatrix` 添加对角线或非对角线元素**。这是因为 `DOF_GeAz` 是一个**绝对旋转自由度**。除非有外部的扭转弹簧直接约束其绝对位置,否则其弹性恢复力为零。

### 3. 求解 `q` 的过程

1.  **构建 `[K]` 和 `F_ext`**: `fill_steady_augmat` 子程序会遍历所有激活的自由度,将弹性项的系数累加到 `GlobalStiffnessMatrix` 中,并将所有外部载荷(重力、气动力、发电机负载、刹车力、齿轮箱摩擦等)累加到 `ExternalForceVector` 中。
    *   对于 `DOF_DrTr``GlobalStiffnessMatrix(DOF_DrTr, DOF_DrTr)` 会包含 `p%DTTorSpr`。
    *   对于 `DOF_GeAz``GlobalStiffnessMatrix(DOF_GeAz, DOF_GeAz)` 及其对应的非对角线元素将保持为零(除非其他自由度通过耦合项贡献了刚度)。

2.  **LU 分解求解**: 在主程序中,调用 LAPACK 的 `DGESV` 等线性求解器来求解 `[K]q = F_ext`。

**关于 `DOF_GeAz` 的求解:**

*   **如果 `GlobalStiffnessMatrix` 是非奇异的**: 求解器会成功找到 `q` 向量,其中包括 `q_DrTr` 和 `q_GeAz`。`q_DrTr` 将是传动轴的静态扭转角。`q_GeAz` 的值将取决于系统中的其他约束和耦合。
*   **如果 `GlobalStiffnessMatrix` 是奇异的**: 如果 `DOF_GeAz` 确实是一个完全不受约束的刚体旋转自由度(即其对应的刚度矩阵行/列全为零),那么 `GlobalStiffnessMatrix` 将是奇异的,`DGESV` 会返回错误(`info != 0`)。这意味着 `q_GeAz` 的绝对值无法通过静力学平衡唯一确定。在实际应用中,这通常需要:
    *   **固定一个参考点**: 例如,假设 `q_GeAz = 0`,然后求解其余自由度。
    *   **引入一个虚拟弹簧**: 给 `DOF_GeAz` 添加一个非常小的虚拟刚度,以消除奇异性,但其物理意义可能不强。
    *   **问题本身就是不适定的**: 如果物理系统在静态下确实存在刚体模式,那么静力学平衡无法唯一确定所有位移。

在风力机传动链的稳态分析中,通常 `q_DrTr` 是我们最关心的静态扭转变形。`q_GeAz` 的绝对值在静态下通常不重要,因为发电机可以以任何角度静止。重要的是扭矩平衡。如果 `ExternalForceVector(DOF_GeAz)` 不为零,则表示系统在该自由度上存在未平衡的净扭矩,这与稳态假设相矛盾,意味着系统并非真正处于静态平衡。
[Timestamp: 2025/11/06 14:17:17]