diff --git a/.obsidian/plugins/copilot/data.json b/.obsidian/plugins/copilot/data.json index 6a7a051..752fffe 100644 --- a/.obsidian/plugins/copilot/data.json +++ b/.obsidian/plugins/copilot/data.json @@ -172,6 +172,20 @@ "stream": true, "displayName": "gemini-2.5-flash-balance", "enableCors": true + }, + { + "name": "ministral-3:14b", + "provider": "ollama", + "enabled": true, + "isBuiltIn": false, + "baseUrl": "https://possibly-engaged-filly.ngrok-free.app/", + "apiKey": "", + "isEmbeddingModel": false, + "capabilities": [ + "vision" + ], + "stream": true, + "enableCors": true } ], "activeEmbeddingModels": [ @@ -302,7 +316,7 @@ "name": "Translate to Chinese", "prompt": "Translate the text below into Chinese:\n 1. Preserve the meaning and tone\n 2. Maintain appropriate cultural context\n 3. Keep formatting and structure\n \n \n\n{copilot-selection}\n\n1. Blade翻译为叶片,flapwise翻译为挥舞,edgewise翻译为摆振,pitch angle翻译成变桨角度,twist angle翻译为扭角,rotor翻译为风轮,turbine、wind turbine翻译为机组、风电机组,span翻译为展向,deflection翻译为变形,mode翻译为模态,normal mode翻译为简正模态,jacket 翻译为导管架,superelement翻译为超单元,shaft翻译为主轴,azimuth、azimuth angle翻译为方位角,neutral axes 翻译为中性轴\n2. Return only the translated text.\n", "showInContextMenu": true, - "modelKey": "gemini-2.5-flash|google" + "modelKey": "ministral-3:14b|ollama" }, { "name": "Summarize", diff --git a/copilot-conversations/20260105_075133__[[Chap_10_EVALUATION_OF_STRUCTURALPROPERTY_MATRICES]]详细展示10-2推导过程.md b/copilot-conversations/20260105_075133__[[Chap_10_EVALUATION_OF_STRUCTURALPROPERTY_MATRICES]]详细展示10-2推导过程.md new file mode 100644 index 0000000..3392b10 --- /dev/null +++ b/copilot-conversations/20260105_075133__[[Chap_10_EVALUATION_OF_STRUCTURALPROPERTY_MATRICES]]详细展示10-2推导过程.md @@ -0,0 +1,115 @@ +--- +epoch: 1767570693319 +modelKey: gemini-2.5-flash|google +tags: + - copilot-conversation +--- + +**user**: [[Chap 10 EVALUATION OF STRUCTURALPROPERTY MATRICES]]详细解释10-2节内容,中文回复 +[Timestamp: 2026/01/05 07:53:32] + +**ai**: 好的,下面是对[[Chap 10 EVALUATION OF STRUCTURALPROPERTY MATRICES]]中10-2部分“质量特性”的详细解释。 + +--- + +### 10-2 质量特性 (MASS PROPERTIES) + +这一节主要讨论结构质量特性的定义和评估,提出了两种主要方法:集中质量矩阵和一致质量矩阵。 + +#### 1. 集中质量矩阵 (Lumped-Mass Matrix) + +* **基本概念**: + * 这是定义结构质量特性最简单的方法。它假设结构的全部质量都集中在定义平移位移的节点上。 + * 这种方法的核心思想是将连续分布的质量离散化为一系列质点。 + +* **质量分配过程**: + * 通常,结构被划分为若干段,节点作为连接点。 + * 每段的质量被假定集中在其两端的节点上。质量如何分配到这些节点通常由静力学原理决定(例如,均匀梁的一半质量分配到每个端点)。 + * 完整结构中任何节点的总质量是连接到该节点的所有段的节点质量贡献之和。例如,在图10-6所示的梁系统中,每个节点都有两段贡献质量,如 $m_1 = m_{1a} + m_{1b}$。 + +* **集中质量矩阵的形式**: + * 对于只定义了平移自由度的系统,集中质量矩阵具有**对角形式**。 + * 公式 (10-24) 展示了这种对角矩阵: + $$ + \mathbf{m} = + \begin{bmatrix} + m_1 & 0 & 0 & \cdots & 0 & \cdots & 0 \\ + 0 & m_2 & 0 & \cdots & 0 & \cdots & 0 \\ + 0 & 0 & m_3 & \cdots & 0 & \cdots & 0 \\ + \vdots & \vdots & \vdots & \ddots & \vdots & \ddots & \vdots \\ + 0 & 0 & 0 & \cdots & m_i & \cdots & 0 \\ + \vdots & \vdots & \vdots & \ddots & \vdots & \ddots & \vdots \\ + 0 & 0 & 0 & \cdots & 0 & \cdots & m_N + \end{bmatrix} + \tag{10-24} + $$ + * **非对角项为零**:该矩阵的非对角项 $m_{ij}$ 为零,因为假设任何质点的加速度只会产生作用在该点上的惯性力,而不会影响其他点。因此,由于点 $i$ 的单位加速度在点 $i$ 产生的惯性力显然等于集中在该点的质量,即质量影响系数 $m_{ii} = m_i$。 + * **旋转自由度**:如果节点处指定了多个平移自由度,则相同的质点质量将与每个平移自由度相关联。然而,与任何旋转自由度相关联的质量通常为零,因为假设质量集中在没有转动惯量的点上。当然,如果一个具有有限转动惯量的刚性质量与旋转自由度相关联,那么该自由度的对角质量系数将是该质量的转动惯量。因此,集中质量矩阵通常是一个对角矩阵,其中旋转自由度的对角元素为零。 + +#### 2. 一致质量矩阵 (Consistent-Mass Matrix) + +* **基本概念**: + * 利用有限元概念,可以通过类似于单元刚度系数分析的程序,评估结构中每个单元的质量影响系数。这种方法得到的质量矩阵被称为一致质量矩阵。 + * 它考虑了单元内部质量的分布以及节点位移和转动对惯性力的影响。 + +* **质量影响系数的评估过程**: + * 考虑一个非均匀梁段(如图10-7所示),其自由度是两端的平移和转动。 + * 假设单元内部的位移由与推导单元刚度时相同的插值函数 $\psi_i(x)$ 定义。 + * **单位加速度引起的加速度分布**:如果梁的左端受到单位角加速度(例如 $\ddot{v}_3 = \ddot{\theta}_a = 1$),则沿其长度会产生加速度分布,表示为 $\ddot{v}(x) = \psi_3(x)\,\ddot{v}_3$ (公式 10-25)。 + * **惯性力**:根据达朗贝尔原理,抵抗此加速度的惯性力是 $f_I(x) = m(x)\;\ddot{v}(x) = m(x)\,\psi_3(x)\,\ddot{v}_3$ (公式 10-26)。 + * **虚位移原理**:与刚度系数的推导类似,质量影响系数被定义为由单位加速度产生的节点惯性力。这些力可以通过虚位移原理从分布惯性力中评估。 + * 例如,要计算 $m_{13}$(在左端施加单位角加速度 $\ddot{v}_3=1$ 时在左端产生的竖向惯性力),可以引入一个竖向虚位移 $\delta v_1$ (如图10-7所示)。 + * 外部虚功 $p_a \delta v_a = \int_0^L f_I(x) \delta v(x) dx$。 + * 将虚位移用插值函数表示,并代入惯性力表达式,最终得到质量影响系数 $m_{13} = \int_0^L m(x)\,\psi_1(x)\,\psi_3(x)\,d x$ (公式 10-27)。 + * 推广到一般情况,任何梁段的质量影响系数 $m_{ij}$ 都可以通过等效表达式 $m_{ij} = \int_0^L m(x)\,\psi_i(x)\,\psi_j(x)\,d x$ 进行计算 (公式 10-28)。 + * **质量矩阵的对称性**:从公式 (10-28) 的对称形式可以看出,质量矩阵(与刚度矩阵一样)是对称的,即 $m_{ij} = m_{ji}$。 + * **均匀质量分布梁的质量矩阵**:当使用三次Hermite插值函数 (公式 10-16) 评估任何直梁段的质量系数时,对于质量均匀分布的梁,可以得到其一致质量矩阵 (公式 10-29): + $$ + \begin{Bmatrix} + f_{I1} \\ + f_{I2} \\ + f_{I3} \\ + f_{I4} + \end{Bmatrix} + = \frac{\bar{m}L}{420} + \begin{bmatrix} + 156 & 54 & 22L & -13L \\ + 54 & 156 & 13L & -22L \\ + 22L & 13L & 4L^2 & -3L^2 \\ + -13L & -22L & -3L^2 & 4L^2 + \end{bmatrix} + \begin{Bmatrix} + \ddot{v}_1 \\ + \ddot{v}_2 \\ + \ddot{v}_3 \\ + \ddot{v}_4 + \end{Bmatrix} + \tag{10-29} + $$ + +* **结构质量矩阵的组装**: + * 当结构单元的质量系数评估完毕后,可以通过与组装刚度矩阵完全相同的叠加过程来建立完整单元组合体的质量矩阵 (参考公式 10-23)。 + * 由此得到的质量矩阵通常具有与刚度矩阵相同的构型(非零项的排列)。 + +* **集中质量与一致质量的比较**: + * **计算工作量**:一致质量系统的动力分析通常比集中质量系统需要显著更多的计算工作量,原因有二: + 1. **矩阵形式**:集中质量矩阵是对角的,而一致质量矩阵有许多非对角项,这导致了所谓的“质量耦合”(mass coupling),意味着一个自由度的加速度会引起其他自由度的惯性力。 + 2. **自由度**:集中质量分析中,旋转自由度可以通过静力凝聚(稍后解释)消除,而一致质量分析必须包含所有旋转和平移自由度。 + +* **示例 E10-2**: + * 这个例子使用示例 E10-1 中的框架结构(图 E10-2a)来说明结构质量矩阵的评估。 + * **集中质量法**: + * 每个构件一半的质量集中在构件两端(图 E10-2b)。 + * 在梁层面,四个贡献的总和作用于侧移自由度 $m_{11}$。 + * 由于这些质点没有转动惯量,其他自由度(旋转自由度)没有质量系数。 + * 最终的集中质量矩阵是一个对角矩阵,只有 $m_{11}$ 有非零值。 + * **一致质量矩阵**: + * 通过依次对每个自由度施加单位加速度,同时约束其他自由度,并根据公式 (10-29) 的系数确定由此产生的惯性力。 + * **侧移加速度** ($\ddot{v}_1=1$,图 E10-2c):公式 (10-29) 的系数只考虑了柱的横向惯性。梁由于平行于其轴线的加速度引起的惯性必须作为刚体质量 (3mL) 添加。 + * **节点转动加速度** ($\ddot{v}_2=1$,图 E10-2d):只引起构件的横向加速度,由此产生的梁和柱的贡献由公式 (10-29) 给出。 + * 最终的一致质量矩阵是一个非对角矩阵,包含了平移和旋转自由度之间的质量耦合项。 + +--- + +总结来说,10-2节详细介绍了结构质量矩阵的两种主要构建方法:集中质量矩阵和一致质量矩阵。集中质量矩阵简单直观,通常是对角矩阵,只考虑平移自由度。一致质量矩阵则基于有限元概念和虚位移原理,通过插值函数考虑了质量的连续分布,通常是非对角矩阵,包含了平移和旋转自由度之间的耦合效应,计算更为精确但也更复杂。 +[Timestamp: 2026/01/05 07:53:49] \ No newline at end of file diff --git a/copilot-conversations/20260107_103211__[[Blade]]详细展示公式推导过程.md b/copilot-conversations/20260107_103211__[[Blade]]详细展示公式推导过程.md new file mode 100644 index 0000000..6d74fa1 --- /dev/null +++ b/copilot-conversations/20260107_103211__[[Blade]]详细展示公式推导过程.md @@ -0,0 +1,1468 @@ +--- +epoch: 1767753131620 +modelKey: gemini-2.5-flash|google +tags: + - 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**: [[Blade]][[FillAugmat]]结合理论和代码,解释叶片部分是如何计算的 +[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}$ 相关。 + +* **代码实现:** + * **叶尖质量的贡献:** + ```fortran + 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}$。 + * **分布式叶片元素的贡献:** + ```fortran + 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$ 成正比。 + +* **代码实现:** + ```fortran + 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}$ 成正比。 + +* **代码实现:** + ```fortran + 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` 的计算中,包含了重力项: + ```fortran + 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)。 + * 气动力和气动扭矩是非保守力,其广义力通过将它们投影到偏速度和偏角速度方向上得到。 + +* **代码实现:** + * 在 `TmpVec1` 和 `TmpVec3` 的计算中,包含了气动力和气动扭矩项: + ```fortran + 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**: [[Blade]][[CalculateForcesMoments]]结合理论和代码,解释叶片部分是如何计算的 +[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`):** + ```fortran + 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`):** + ```fortran + 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`):** + ```fortran + 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)%Force` 和 `u%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$ 相关的部分(用于广义力向量)。这里的偏力/偏力矩与广义质量矩阵的构建直接相关。 + +* **代码实现:** + * **叶尖质量的贡献:** + ```fortran + 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` 是从叶片根部到叶尖的位置向量。 + * **分布式叶片元素的贡献:** + ```fortran + 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) 描述了广义气动力。这些都是广义力向量的组成部分。 + +* **代码实现:** + * **叶尖贡献:** + ```fortran + 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(...)` 将这些力转换为关于叶片根部的力矩。 + * **分布式叶片元素贡献:** + ```fortran + 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` 等)是构建系统动力学方程的**中间结果**。 + +* **`PFrcS0B` 和 `PMomH0B`** (Partial Forces/Moments): 这些是与广义加速度 $\ddot{q}$ 相关的系数,它们在 `FillAugMat` 中与偏速度/偏角速度进行点积,用于填充**广义质量矩阵** $[C(q,t)]$。 +* **`FrcS0Bt` 和 `MomH0Bt`** (Total Forces/Moments): 这些是包含了所有主动力(气动力、重力、弹性力、阻尼力)以及速度相关的惯性力(科里奥利力、离心力)的总和。它们在 `FillAugMat` 中与偏速度/偏角速度进行点积,用于填充**广义力向量** $\{-f(\dot{q},q,t)\}$。 + +简而言之,`CalculateForcesMoments` 负责将外部输入(如气动载荷)和系统内部状态(如位置、速度、加速度)转化为作用在叶片上的具体物理力和力矩,并进一步分解为“偏”量和“总”量,为后续在 `FillAugMat` 中构建完整的广义动力学方程做准备。它将 [[Blade]] 笔记中描述的各种力(惯性、重力、气动)的物理表达式,通过具体的数值计算和向量运算实现出来。 +[Timestamp: 2026/01/07 14:08:00] + +**user**: [[Blade]][[CalculateAngularPosVelPAcc]]结合理论和代码,解释叶片部分是如何计算的 +[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,:)` (轮毂的偏角速度):** + ```fortran + 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,:)` (轮毂偏角速度的一阶导数):** + ```fortran + 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}$ 无关的部分):** + ```fortran + 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,:)`):** + ```fortran + 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`):** + ```fortran + 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,:)`):** + 代码中这部分被注释掉了: + ```fortran + ! 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}$ 无关的部分):** + ```fortran + 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**: [[Blade]][[CalculatePositions]]结合理论和代码,解释代码的作用 +[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)`):** + ```fortran + 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))的相对位置向量。 + +* **代码实现:** + ```fortran + 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))的绝对位置向量。 + +* **代码实现:** + ```fortran + RtHSdat%rS (:,K,p%TipNode) = RtHSdat%rQS (:,K,p%TipNode) + RtHSdat%rQ + ``` + 这行代码将从轮毂旋转中心到叶尖的相对位置 `rQS` 加上从惯性系原点到轮毂旋转中心的绝对位置 `RtHSdat%rQ`,从而得到从惯性系原点到叶尖的绝对位置 `rS`。 + * `RtHSdat%rQ`: 这是在叶片循环之前计算的,表示从惯性系原点到轮毂旋转中心(点 Q)的绝对位置向量。 + +#### 4. 其他关键位置向量 + +除了叶片柔性点的位置,子程序还计算了其他与叶片相关的关键位置向量: + +* **`RtHSdat%rPS0(:,K)` (从摆振销到叶片根部的位置):** + ```fortran + 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%rS0S` 和 `RtHSdat%rPS0` 等作为力臂。 +4. **支持运动学计算:** 准确的位置信息是计算速度和加速度(包括偏速度和偏角速度)的基础,这些运动学量在 `CalculateAngularPosVelPAcc` 和 `CalculateLinearVelPAcc` 中被进一步计算。 + +通过这些详细的位置计算,`CalculatePositions` 确保了风力机叶片在复杂三维运动和柔性变形下的几何构型被准确地捕捉,为后续的动力学方程构建提供了坚实的基础。 +[Timestamp: 2026/01/07 14:29:57] + +**user**: [[Blade]][[Coeff]]结合理论和代码,解释叶片部分是如何计算的 +[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)$ 可以包含由气动偏移引起的力矩。这意味着需要知道气动力作用点(气动中心)相对于叶片参考点的位置。 + +* **代码作用:** + ```fortran + 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% 弦长处)在叶片局部坐标系 `n1` 和 `n2` 方向上的分量 `p%rSAerCenn1` 和 `p%rSAerCenn2`。 + * `p%PitchAxis(K,J)`: 叶片 $K$ 元素 $J$ 的桨距轴位置(相对于弦长)。 + * `p%Chord(J)`: 叶片元素 $J$ 的弦长。 + * `TmpDist`: 气动中心与参考点 S 沿弦长的距离。 + * `p%SAeroTwst(J)`, `p%CAeroTwst(J)`: 气动扭转的正弦和余弦值,用于将沿弦长的距离分解到叶片局部 `j1` 和 `j2` 轴。 + * `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}$。这些是计算叶片总质量、质心和转动惯量的基础。 + +* **代码作用:** + ```fortran + 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}$,它们通过对叶片分布式质量和模态形状函数进行积分得到。 + +* **代码作用:** + ```fortran + 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}$。代码中还计算了离心刚化效应引起的刚度项。 + +* **代码作用:** + ```fortran + 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}$。 + +* **代码作用:** + ```fortran + 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'$ 相关。 + +* **代码作用:** + ```fortran + 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` 子程序中计算叶片柔性点的位移,如前所述。它们描述了叶片柔性变形的几何特性。 + +* **代码作用:** + ```fortran + ! 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**: + +```pub fn shp_array(fract: f64, // Fractional distance along the beam + flexl: f64, // Length of the flexible beam + mod_shp_ary: &Array1, // 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$ 是沿梁的无量纲距离(`fract`),$C_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` 函数中的循环逻辑: + +```rust +// 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=2$ 且 `deriv=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` 是 2,`flexl.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 实现):** + ```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. **定义模态形状系数数组:** + ```python + # 假设 flexl = 1.0 (无量纲化,因为形状函数本身就是无量纲的,通常在绘图时将flexl设为1) + # 如果需要绘制实际物理长度上的形状,则flexl应为实际叶片柔性段长度,例如 60 米。 + # 这里我们先绘制无量纲形状,所以 flexl=1.0,fract 对应 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` 值范围:** + ```python + fract_values = np.linspace(0.0, 1.0, 100) # 从 0 到 1 取 100 个点 + ``` + +4. **计算每个模态形状函数的值:** + ```python + # 计算第一阶挥舞模态形状 + 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. **绘制图形:** + ```python + 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] \ No newline at end of file diff --git a/copilot-conversations/20260109_152054__基于凯恩方程原理,[[Tower]]详细展示公式推导过程.md b/copilot-conversations/20260109_152054__基于凯恩方程原理,[[Tower]]详细展示公式推导过程.md new file mode 100644 index 0000000..e34ec24 --- /dev/null +++ b/copilot-conversations/20260109_152054__基于凯恩方程原理,[[Tower]]详细展示公式推导过程.md @@ -0,0 +1,905 @@ +--- +epoch: 1767943254796 +modelKey: gemini-2.5-flash|google +tags: + - copilot-conversation +--- + +**user**: 基于凯恩方程原理,[[Tower]]详细展示公式推导过程 +[Timestamp: 2026/01/09 15:20:54] + +**ai**: 基于凯恩方程原理,[[Tower]]笔记详细展示了塔架的公式推导过程,主要涉及广义惯性力、广义弹性力、广义阻尼力、广义重力以及广义气动力。 + +### 1. 广义惯性力 (Generalized Inertia Forces) + +塔架的分布式特性带来了与塔架弹性、塔架阻尼、塔架气动特性和塔架重量相关的广义惯性力和广义主动力。笔记中提到,为了简化模型,消除了塔架质量调谐器,并消除了塔架刚度调谐器对重力去刚化载荷的影响。 + +广义惯性力 $F_r^* \Big|_T$ 的定义如下: +$$ +F_r^* \Big|_T = - \int_0^{TwFlexL} \mu^T (h) \cdot {}^E v_r^T (h) \cdot {}^E a^T (h)dh - YawBrMass {}^E v_r^O \cdot {}^E a^O \quad (r = 1, 2, \ldots, 22) \tag{1} +$$ +其中,$\mu^T (h)$ 是调整后的塔架质量密度,定义为: +$$ +\text{where} \quad \mu^T (h) = AdjTwMa \cdot TMassDen(h)\tag{1} +$$ +这里,$AdjTwMa$ 是调整系数,$TMassDen(h)$ 是塔架沿高度 $h$ 的质量密度。${}^E v_r^T (h)$ 是塔架上点 T 的广义速度,${}^E a^T (h)$ 是塔架上点 T 的广义加速度。$YawBrMass$ 是偏航轴承质量,${}^E v_r^O$ 和 ${}^E a^O$ 分别是偏航轴承处的广义速度和广义加速度。 + +将加速度项展开为广义坐标 $\ddot{q}_i$ 和 $\dot{q}_i$ 的形式,广义惯性力可以表示为: +$$ +F_r^* \Big|_T = - \int_0^{TwrFlexL} \mu^T (h) \cdot {}^E \mathbf{v}_r^T (h) \cdot \left\{ \left( \sum_{i=1}^{10} {}^E \mathbf{v}_i^T (h) \ddot{q}_i \right) + \left[ \sum_{i=4}^{10} \frac{d}{dt} \left( {}^E \mathbf{v}_i^T (h) \right) \dot{q}_i \right] \right\} dh - YawBrMass {}^E \mathbf{v}_r^O \cdot \left\{ \left( \sum_{i=1}^{10} {}^E \mathbf{v}_i^O \ddot{q}_i \right) + \left[ \sum_{i=4}^{10} \frac{d}{dt} \left( {}^E \mathbf{v}_i^O \right) \dot{q}_i \right] \right\} \quad (r=1,2,\ldots,10)\tag{2} +$$ +从上述方程中,可以提取出质量矩阵 $[C(\mathbf{q},t)]_T$ 和非线性惯性力项 $\left\{ - f(\dot{q},q,t) \right\} \Big|_T$: +$$ +[C(\mathbf{q},t)]_T (Row, Col) = \int_0^{TwrFlexL} \mu^T (h) {}^E \mathbf{v}_{Row}^T (h) \cdot {}^E \mathbf{v}_{Col}^T (h)dh - YawBrMass {}^E \mathbf{v}_{Row}^O \cdot {}^E \mathbf{v}_{Col}^O \quad (Row, Col = 1, 2, \ldots, 10)\tag{3} +$$ +$$ +\left\{ - f(\dot{q},q,t) \right\} \Big|_T (Row) = - \int_0^{TwrFlexL} \mu^T (h) {}^E \mathbf{v}_{Row}^T (h) \cdot \left( \sum_{i=4}^{10} \frac{d}{dt} \left[ {}^E \mathbf{v}_i^T (h) \right] \dot{q}_i \right) dh - YawBrMass {}^E \mathbf{v}_{Row}^O \cdot \left[ \sum_{i=4}^{10} \frac{d}{dt} \left( {}^E \mathbf{v}_i^O \right) \dot{q}_i \right] \quad (Row = 1,2,\ldots,10)\tag{4} +$$ + +### 2. 广义弹性力 (Generalized Elastic Forces) + +广义弹性力 $F_{r \Big| ElasticT}$ 是通过对弹性势能 $V'^T$ 求偏导得到的: +$$ +F_{r \Big| ElasticT} = - \frac{\partial V'^T}{\partial q_r} \quad (r = 1,2,\ldots,22)\tag{5} +$$ +具体形式如下,其中考虑了塔架前后 (TFA) 和侧向 (TSS) 的两个模态: +$$ +F_{r \Big| ElasticT} = \left\{ +\begin{array}{ll} +-k_{11}^{'TFA} q_{TFA1} - k_{12}^{'TFA} q_{TFA2} & \text{for } r=TFA1 \\ +-k_{11}^{'TSS} q_{TSS1} - k_{12}^{'TSS} q_{TSS2} & \text{for } r=TSS1 \\ +-k_{21}^{'TFA} q_{TFA1} - k_{22}^{'TFA} q_{TFA2} & \text{for } r=TFA2 \\ +-k_{21}^{'TSS} q_{TSS1} - k_{22}^{'TSS} q_{TSS2} & \text{for } r=TSS2 \\ +0 & \text{otherwise} +\end{array} +\right.\tag{6} +$$ +其中,$k_{\ i j}^{\,\prime T F A}$ 和 $k_{{i j}}^{\,\prime{T S S}}$ 分别是塔架在前后和侧向方向上的广义刚度,不包括重力去刚化效应。它们通过积分形式定义: +$$ +k_{ij}^{'TFA} = \sqrt{FAStTunr(i) FAStTunr(j)} \int_0^{TwrFlexL} EI^{TFA}(h) \frac{d^2 \phi_i^{TFA}(h)}{dh^2} \frac{d^2 \phi_j^{TFA}(h)}{dh^2} dh \quad (i, j = 1,2) \text{ (which is symmetric)}\tag{7} +$$ +其中,$EI^{TFA}(h)$ 是调整后的塔架前后方向的弯曲刚度: +$$ +EI^{TFA}(h) = AdjFASt \cdot TwFAStif(h)\tag{8} +$$ +类似地,侧向的广义刚度为: +$$ +k_{ij}^{'TSS} = \sqrt{SSStTunr(i) SSStTunr(j)} \int_0^{TwrFlexL} EI^{TSS}(h) \frac{d^2 \phi_i^{TSS}(h)}{dh^2} \frac{d^2 \phi_j^{TSS}(h)}{dh^2} dh \quad (i, j = 1,2) \text{ (which is symmetric)}\tag{9} +$$ +其中,$EI^{TSS}(h)$ 是调整后的塔架侧向的弯曲刚度: +$$ +EI^{TSS}(h) = AdjSSSt \cdot TwSSStif(h)\tag{10} +$$ +这些广义刚度中的积分系数代表了各个模态刚度调谐,允许用户在各个模态之间改变塔的刚度,从而更好地匹配塔的固有频率。 + +对于弹性力,质量矩阵 $[C(q,t)]|_{\text{Elastic}T}$ 为零,非线性惯性力项 $\{-f(\dot{q},q,t)\}|_{\text{Elastic}T}$ 包含了弹性力项: +$$ +[C(q,t)]|_{\text{Elastic}T} = 0\tag{15} +$$ +$$ +\{-f(\dot{q},q,t)\}|_{\text{Elastic}T} = \begin{Bmatrix} +\vdots \\ +\vdots \\ +\vdots \\ +-k_{11}^{'TFA} q_{TFA1} - k_{12}^{'TFA} q_{TFA2} \\ +-k_{11}^{'TSS} q_{TSS1} - k_{12}^{'TSS} q_{TSS2} \\ +-k_{21}^{'TFA} q_{TFA1} - k_{22}^{'TFA} q_{TFA2} \\ +-k_{21}^{'TSS} q_{TSS1} - k_{22}^{'TSS} q_{TSS2} \\ +\vdots \\ +\vdots \\ +\vdots \\ +\end{Bmatrix}\tag{16} +$$ + +### 3. 广义阻尼力 (Generalized Damping Forces) + +当使用瑞利阻尼技术,假设阻尼与刚度成比例时,广义阻尼力 $F_r |_{\text{Damp}T}$ 表示为: +$$ +F_r |_{\text{Damp}T} = \begin{cases} +- \frac{\zeta_1^{TFA} k_{11}^{'TFA}}{\pi f_1^{'TFA}} \dot{q}_{TFA1} - \frac{\zeta_2^{TFA} k_{12}^{'TFA}}{\pi f_2^{'TFA}} \dot{q}_{TFA2} & \text{for } r=TFA1 \\ +- \frac{\zeta_1^{TSS} k_{11}^{'TSS}}{\pi f_1^{'TSS}} \dot{q}_{TSS1} - \frac{\zeta_2^{TSS} k_{12}^{'TSS}}{\pi f_2^{'TSS}} \dot{q}_{TSS2} & \text{for } r=TSS1 \\ +- \frac{\zeta_1^{TFA} k_{21}^{'TFA}}{\pi f_1^{'TFA}} \dot{q}_{TFA1} - \frac{\zeta_2^{TFA} k_{22}^{'TFA}}{\pi f_2^{'TFA}} \dot{q}_{TFA2} & \text{for } r=TFA2 \\ +- \frac{\zeta_1^{TSS} k_{21}^{'TSS}}{\pi f_1^{'TSS}} \dot{q}_{TSS1} - \frac{\zeta_2^{TSS} k_{22}^{'TSS}}{\pi f_2^{'TSS}} \dot{q}_{TSS2} & \text{for } r=TSS2 \\ +0 & \text{otherwise} +\end{cases}\tag{11} +$$ +其中,$\zeta_{i}^{T F A}$ 和 $\zeta_{i}^{T S S}$ 分别表示塔架在前后向和侧向上的结构阻尼比,而 $f_{\ i}^{\,\prime T F A}$ 和 $f_{\ i}^{\prime T S S}$ 分别表示塔架在前后向和侧向上的固有频率,不考虑塔顶质量和重力软化效应。这些固有频率定义为: +$$ +f_{\;\;i}^{\;\prime^{T F A}}=\frac{1}{2\pi}\sqrt{\frac{k_{\;i i}^{\prime^{T F A}}}{m_{\;i i}^{\prime^{T F A}}}}\;\;\;\;\;\mathrm{and}\;\;\;\;\;\;\;f_{\;i}^{\;\prime^{T S S}}=\frac{1}{2\pi}\sqrt{\frac{k_{\;i i}^{\prime T S S}}{m_{\;i i}^{\prime T S S}}}\tag{12} +$$ +这里,$m_{\;i i}^{\;\prime T F A}$ 和 $m_{\ i i}^{\prime T S S}$ 分别表示在塔顶质量效应忽略的情况下,第 $i$ 阶模态在前后方向和左右方向上的广义质量: +$$ +m_{\ i j}^{\prime^{T F A}}=\int_{0}^{T w r F l e x L}\mu^{T}\left(h\right)\phi_{i}^{T F A}\left(h\right)\phi_{j}^{T F A}\left(h\right)d h\quad\left(i,j=1,2\right)\tag{13} +$$ +$$ +m_{\it i j}^{\prime T S S}=\int_{0}^{T w r F l e x L}\mu^{T}\left(h\right)\phi_{i}^{T S S}\left(h\right)\phi_{j}^{T S S}\left(h\right)d h\quad\left(i,j=1,2\right)\tag{14} +$$ +对于阻尼力,质量矩阵 $[C(q,t)]|_{\text{Damp}T}$ 为零,非线性惯性力项 $\{-f(\dot{q},q,t)\}|_{\text{Damp}T}$ 包含了阻尼力项: +$$ +[C(q,t)]|_{\text{Damp}T} = 0\tag{17} +$$ +$$ +\{-f(\dot{q},q,t)\}|_{\text{Damp}T} = \begin{Bmatrix} +\vdots \\ +\vdots \\ +\vdots \\ +- \frac{\zeta_1^{TFA} k_{11}^{'TFA}}{\pi f_1^{'TFA}} \dot{q}_{TFA1} - \frac{\zeta_2^{TFA} k_{12}^{'TFA}}{\pi f_2^{'TFA}} \dot{q}_{TFA2} \\ +- \frac{\zeta_1^{TSS} k_{11}^{'TSS}}{\pi f_1^{'TSS}} \dot{q}_{TSS1} - \frac{\zeta_2^{TSS} k_{12}^{'TSS}}{\pi f_2^{'TSS}} \dot{q}_{TSS2} \\ +- \frac{\zeta_1^{TFA} k_{21}^{'TFA}}{\pi f_1^{'TFA}} \dot{q}_{TFA1} - \frac{\zeta_2^{TFA} k_{22}^{'TFA}}{\pi f_2^{'TFA}} \dot{q}_{TFA2} \\ +- \frac{\zeta_1^{TSS} k_{21}^{'TSS}}{\pi f_1^{'TSS}} \dot{q}_{TSS1} - \frac{\zeta_2^{TSS} k_{22}^{'TSS}}{\pi f_2^{'TSS}} \dot{q}_{TSS2} \\ +\vdots \\ +\vdots \\ +\vdots +\end{Bmatrix}\tag{18} +$$ + +### 4. 广义重力 (Generalized Gravitational Forces) + +广义重力 $F_r |_{\text{Grav}T}$ 考虑了塔架自身的重力以及偏航轴承的重力: +$$ +F_r |_{\text{Grav}T} = \int_{0}^{\text{TwrFlexL}} \! {}^E \mathbf{v}_r^T(h) \cdot [-\mu^T(h) \mathbf{g}\mathbf{z}_2] \, dh + {}^E \mathbf{v}_r^O \cdot (-\text{YawBrMass} \cdot \mathbf{g}\mathbf{z}_2) \quad (r=3,4,...,10)\tag{19} +$$ +其中,$\mathbf{g}$ 是重力加速度,$\mathbf{z}_2$ 是垂直方向的单位向量。 + +对于重力,质量矩阵 $[C(q,t)]|_{\text{Grav}T}$ 为零,非线性惯性力项 $\{-f(\dot{q},q,t)\}|_{\text{Grav}T}$ 包含了重力项: +$$ +[C(q,t)]|_{\text{Grav}T} = 0\tag{20} +$$ +$$ +\{-f(\dot{q},q,t)\}|_{\text{Grav}T} (\text{Row}) = - \int_{0}^{\text{TwrFlexL}} \! \mu^T(h) g {}^E \mathbf{v}_{\text{Row}}^T(h) \cdot \mathbf{z}_2 \, dh - \text{YawBrMass} \cdot g {}^E \mathbf{v}_{\text{Row}}^O \cdot \mathbf{z}_2 \quad (Row=3,4,...,10)\tag{21} +$$ + +### 5. 广义气动力 (Generalized Aerodynamic Forces) + +广义气动力 $F_r |_{\text{Aero}T}$ 是通过对塔架上每单位高度的气动力 $\mathbf{F}_{\text{Aero}T}^T(h)$ 和气动弯矩 $\mathbf{M}_{\text{Aero}T}^F(h)$ 进行积分得到的: +$$ +F_r |_{\text{Aero}T} = \int_{0}^{\text{TwrFlexL}} \! \left[ {}^E \mathbf{v}_r^T(h) \cdot \mathbf{F}_{\text{Aero}T}^T(h) + {}^E \boldsymbol{\omega}_r^F(h) \cdot \mathbf{M}_{\text{Aero}T}^F(h) \right] dh \quad (r=1,2,...,10)\tag{22} +$$ +其中,$F_{A e r o T}^{T}\left(h\right)$ 和 $M_{A e r o T}^{F}\left(h\right)$ 分别是施加在塔架上点 T 的每单位高度的气动力和气动弯矩。 + +对于气动力,质量矩阵 $[C(q,t)]|_{\text{Aero}T}$ 为零,非线性惯性力项 $\{-f(\dot{q},q,t)\}|_{\text{Aero}T}$ 包含了气动力项: +$$ +[C(q,t)]|_{\text{Aero}T} = 0\tag{23} +$$ +$$ +\{-f(\dot{q},q,t)\}|_{\text{Aero}T} (\text{Row}) = \int_{0}^{\text{TwrFlexL}} \! \left[ {}^E \mathbf{v}_{\text{Row}}^T(h) \cdot \mathbf{F}_{\text{Aero}T}^T(h) + {}^E \boldsymbol{\omega}_{\text{Row}}^F(h) \cdot \mathbf{M}_{\text{Aero}T}^F(h) \right] dh \quad (Row=1,2,...,10)\tag{24} +$$ + +这些公式共同构成了基于凯恩方程原理的塔架动力学模型,通过广义力来描述塔架在各种载荷下的响应。 +[Timestamp: 2026/01/09 15:21:18] + +**user**: [[Tower]][[FillAugmat]]结合理论和代码,解释塔架部分是如何计算的 +[Timestamp: 2026/01/12 11:25:11] + +**ai**: 好的,我们来结合[[Tower]]笔记中的理论和[[FillAugmat]]子程序中的代码,解释塔架部分是如何计算的。 + +在OpenFAST动力学模型中,塔架被视为一个柔性体,其运动通过广义坐标来描述。[[Tower]]笔记详细推导了塔架的广义惯性力、弹性力、阻尼力、重力和气动力。[[FillAugmat]]子程序则负责将这些力项和质量项组装到增广矩阵 `AugMat` 中,该矩阵用于求解系统的动力学方程。 + +### 理论回顾 (来自 [[Tower]] 笔记) + +塔架的动力学方程可以表示为广义质量矩阵 $[C(\mathbf{q},t)]$ 乘以广义加速度 $\ddot{\mathbf{q}}$,加上广义力 $\{-f(\dot{q},q,t)\}$ 等于零的形式。 + +1. **广义惯性力 ($F_r^* \Big|_T$)**: + 这是由塔架分布式质量和偏航轴承质量引起的。 + * **质量矩阵项**: + $$ + [C(\mathbf{q},t)]_T (Row, Col) = \int_0^{TwrFlexL} \mu^T (h) {}^E \mathbf{v}_{Row}^T (h) \cdot {}^E \mathbf{v}_{Col}^T (h)dh - YawBrMass {}^E \mathbf{v}_{Row}^O \cdot {}^E \mathbf{v}_{Col}^O \quad (Row, Col = 1, 2, \ldots, 10)\tag{3} + $$ + 其中 $\mu^T(h)$ 是调整后的塔架质量密度,${}^E \mathbf{v}_{Row}^T (h)$ 和 ${}^E \mathbf{v}_{Col}^T (h)$ 是塔架上点的广义速度,${}^E \mathbf{v}_{Row}^O$ 和 ${}^E \mathbf{v}_{Col}^O$ 是偏航轴承处的广义速度。 + * **非线性惯性力项**: + $$ + \left\{ - f(\dot{q},q,t) \right\} \Big|_T (Row) = - \int_0^{TwrFlexL} \mu^T (h) {}^E \mathbf{v}_{Row}^T (h) \cdot \left( \sum_{i=4}^{10} \frac{d}{dt} \left[ {}^E \mathbf{v}_i^T (h) \right] \dot{q}_i \right) dh - YawBrMass {}^E \mathbf{v}_{Row}^O \cdot \left[ \sum_{i=4}^{10} \frac{d}{dt} \left( {}^E \mathbf{v}_i^O \right) \dot{q}_i \right] \quad (Row = 1,2,\ldots,10)\tag{4} + $$ + 这部分包含了科里奥利力和离心力等速度相关的非线性项。 + +2. **广义弹性力 ($F_{r \Big| ElasticT}$)**: + 由塔架的弹性变形引起,与广义坐标 $q_r$ 相关。 + $$ + F_{r \Big| ElasticT} = - \frac{\partial V'^T}{\partial q_r} \quad (r = 1,2,\ldots,22)\tag{5} + $$ + 具体形式为: + $$ + \{-f(\dot{q},q,t)\}|_{\text{Elastic}T} = \begin{Bmatrix} + \vdots \\ + -k_{11}^{'TFA} q_{TFA1} - k_{12}^{'TFA} q_{TFA2} \\ + -k_{11}^{'TSS} q_{TSS1} - k_{12}^{'TSS} q_{TSS2} \\ + -k_{21}^{'TFA} q_{TFA1} - k_{22}^{'TFA} q_{TFA2} \\ + -k_{21}^{'TSS} q_{TSS1} - k_{22}^{'TSS} q_{TSS2} \\ + \vdots + \end{Bmatrix}\tag{16} + $$ + 其中 $k_{ij}^{'TFA}$ 和 $k_{ij}^{'TSS}$ 是广义刚度系数。 + +3. **广义阻尼力 ($F_r |_{\text{Damp}T}$)**: + 假设阻尼与刚度成比例(瑞利阻尼),与广义速度 $\dot{q}_r$ 相关。 + $$ + F_r |_{\text{Damp}T} = \begin{cases} + - \frac{\zeta_1^{TFA} k_{11}^{'TFA}}{\pi f_1^{'TFA}} \dot{q}_{TFA1} - \frac{\zeta_2^{TFA} k_{12}^{'TFA}}{\pi f_2^{'TFA}} \dot{q}_{TFA2} & \text{for } r=TFA1 \\ + \vdots + \end{cases}\tag{11} + $$ + 具体形式为: + $$ + \{-f(\dot{q},q,t)\}|_{\text{Damp}T} = \begin{Bmatrix} + \vdots \\ + - \frac{\zeta_1^{TFA} k_{11}^{'TFA}}{\pi f_1^{'TFA}} \dot{q}_{TFA1} - \frac{\zeta_2^{TFA} k_{12}^{'TFA}}{\pi f_2^{'TFA}} \dot{q}_{TFA2} \\ + \vdots + \end{Bmatrix}\tag{18} + $$ + +4. **广义重力 ($F_r |_{\text{Grav}T}$)**: + 由塔架自身质量和偏航轴承质量在重力场中的作用引起。 + $$ + F_r |_{\text{Grav}T} = \int_{0}^{\text{TwrFlexL}} \! {}^E \mathbf{v}_r^T(h) \cdot [-\mu^T(h) \mathbf{g}\mathbf{z}_2] \, dh + {}^E \mathbf{v}_r^O \cdot (-\text{YawBrMass} \cdot \mathbf{g}\mathbf{z}_2) \quad (r=3,4,...,10)\tag{19} + $$ + 对应的非线性惯性力项为: + $$ + \{-f(\dot{q},q,t)\}|_{\text{Grav}T} (\text{Row}) = - \int_{0}^{\text{TwrFlexL}} \! \mu^T(h) g {}^E \mathbf{v}_{\text{Row}}^T(h) \cdot \mathbf{z}_2 \, dh - \text{YawBrMass} \cdot g {}^E \mathbf{v}_{\text{Row}}^O \cdot \mathbf{z}_2 \quad (Row=3,4,...,10)\tag{21} + $$ + +5. **广义气动力 ($F_r |_{\text{Aero}T}$)**: + 由作用在塔架上的气动力和气动弯矩引起。 + $$ + F_r |_{\text{Aero}T} = \int_{0}^{\text{TwrFlexL}} \! \left[ {}^E \mathbf{v}_r^T(h) \cdot \mathbf{F}_{\text{Aero}T}^T(h) + {}^E \boldsymbol{\omega}_r^F(h) \cdot \mathbf{M}_{\text{Aero}T}^F(h) \right] dh \quad (r=1,2,...,10)\tag{22} + $$ + 对应的非线性惯性力项为: + $$ + \{-f(\dot{q},q,t)\}|_{\text{Aero}T} (\text{Row}) = \int_{0}^{\text{TwrFlexL}} \! \left[ {}^E \mathbf{v}_{\text{Row}}^T(h) \cdot \mathbf{F}_{\text{Aero}T}^T(h) + {}^E \boldsymbol{\omega}_{\text{Row}}^F(h) \cdot \mathbf{M}_{\text{Aero}T}^F(h) \right] dh \quad (Row=1,2,...,10)\tag{24} + $$ + +### 代码实现 (来自 [[FillAugmat]] 子程序) + +`FillAugMat` 子程序的目标是构建增广矩阵 `AugMat`。这个矩阵的结构通常是左上角为质量矩阵 $[M]$,右侧为力向量 $[F]$,即 `[M | F]`。在OpenFAST中,它实际上是 `[C(q,t) | -f(qd,q,t)]` 的形式,其中 `C(q,t)` 是广义质量矩阵,`-f(qd,q,t)` 是广义力向量。 + +我们重点关注塔架相关的计算部分: + +1. **初始化 `AugMat`**: + ```fortran + AugMat = 0.0 + ``` + 在开始计算之前,`AugMat` 被初始化为零。 + +2. **偏航轴承质量效应 (Yaw Bearing Mass Effects)**: + 这部分对应于[[Tower]]笔记中公式 (3) 和 (4) 中与 `YawBrMass` 相关的项。 + ```fortran + DO L = 1,p%DOFs%NPTTE ! Loop through all active (enabled) tower DOFs that contribute to the QD2T-related linear accelerations of the yaw bearing (point O) + DO I = L,p%DOFs%NPTTE ! Loop through all active (enabled) tower DOFs greater than or equal to L + AugMat(p%DOFs%PTTE(I),p%DOFs%PTTE(L)) = p%YawBrMass*DOT_PRODUCT( RtHSdat%PLinVelEO(p%DOFs%PTTE(I),0,:), & ! [C(q,t)]T of YawBrMass + RtHSdat%PLinVelEO(p%DOFs%PTTE(L),0,:) ) + ENDDO ! I - All active (enabled) tower DOFs greater than or equal to L + ENDDO ! L - All active (enabled) tower DOFs that contribute to the QD2T-related linear accelerations of the yaw bearing (point O) + + TmpVec1 = -p%YawBrMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEOt ) ! The portion of FrcT0Trbt associated with the YawBrMass + DO I = 1,p%DOFs%NPTTE ! Loop through all active (enabled) tower DOFs that contribute to the QD2T-related linear accelerations of the yaw bearing (point O) + AugMat(p%DOFs%PTTE(I), p%NAug) = DOT_PRODUCT( RtHSdat%PLinVelEO(p%DOFs%PTTE(I),0,:), & ! {-f(qd,q,t)}T + {-f(qd,q,t)}GravT of YawBrMass + TmpVec1 ) ! NOTE: TmpVec1 is still the portion of FrcT0Trbt associated with YawBrMass + ENDDO ! I - All active (enabled) tower DOFs that contribute to the QD2T-related linear accelerations of the yaw bearing (point O) + ``` + * `p%DOFs%NPTTE` 是塔架自由度的数量。 + * `p%YawBrMass` 是偏航轴承质量。 + * `RtHSdat%PLinVelEO` 是偏航轴承点 O 的广义速度偏导数,用于计算质量矩阵项。 + * `RtHSdat%LinAccEOt` 是偏航轴承点 O 的线性加速度,用于计算非线性惯性力项(包括重力)。 + * `p%NAug` 是增广矩阵的最后一列,用于存储力向量。 + * `TmpVec1` 包含了偏航轴承的重力 (`p%Gravity*CoordSys%z2`) 和非线性惯性力 (`RtHSdat%LinAccEOt`)。 + +3. **塔架分布式质量、重力、气动力和水动力效应**: + 这部分对应于[[Tower]]笔记中公式 (3), (4), (19), (21), (22), (24) 中与塔架分布式质量相关的积分项。 + ```fortran + DO J = 1,p%TwrNodes + ! ... (计算质量矩阵项) + DO L = 1,p%DOFs%NPTTE + DO I = L,p%DOFs%NPTTE + AugMat(p%DOFs%PTTE(I),p%DOFs%PTTE(L)) = AugMat(p%DOFs%PTTE(I),p%DOFs%PTTE(L)) & + + p%TElmntMass(J) *DOT_PRODUCT( RtHSdat%PLinVelET(J,p%DOFs%PTTE(I),0,:), & + RtHSdat%PLinVelET(J,p%DOFs%PTTE(L),0,:) ) & ! [C(q,t)]T + [C(q,t)]HydroT + - abs(p%DHNodes(J))*DOT_PRODUCT( RtHSdat%PLinVelET(J,p%DOFs%PTTE(I),0,:), & + RtHSdat%PFTHydro (:,J,p%DOFs%PTTE(L) ) ) & + - abs(p%DHNodes(J))*DOT_PRODUCT( RtHSdat%PAngVelEF(J,p%DOFs%PTTE(I),0,:), & + RtHSdat%PMFHydro (:,J,p%DOFs%PTTE(L) ) ) + ENDDO + ENDDO + + ! ... (计算力向量项) + TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*abs(p%DHNodes(J)) & + - p%TElmntMass(J)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccETt(:,J) ) ! The portion of FrcT0Trbt associated with tower element J + TmpVec3 = ( RtHSdat%MFHydrot(:,J) )*abs(p%DHNodes(J)) ! The external moment applied to tower element J + DO I = 1,p%DOFs%NPTTE + AugMat(p%DOFs%PTTE(I), p%NAug) = AugMat(p%DOFs%PTTE(I), p%NAug) & ! {-f(qd,q,t)}T + {-f(qd,q,t)}GravT + {-f(qd,q,t)}AeroT + {-f(qd,q,t)}HydroT + + DOT_PRODUCT( RtHSdat%PLinVelET(J,p%DOFs%PTTE(I),0,:), TmpVec1 ) & ! NOTE: TmpVec1 is still the portion of FrcT0Trbt associated with tower element J + + DOT_PRODUCT( RtHSdat%PAngVelEF(J,p%DOFs%PTTE(I),0,:), TmpVec3 ) + ENDDO + ENDDO + ``` + * `p%TwrNodes` 是塔架离散化的节点数量。 + * `p%TElmntMass(J)` 是第 `J` 个塔架单元的质量。 + * `RtHSdat%PLinVelET(J,...)` 和 `RtHSdat%PAngVelEF(J,...)` 是塔架单元 `J` 的广义速度偏导数,用于计算质量矩阵项。 + * `RtHSdat%FTHydrot(:,J)` 和 `RtHSdat%MFHydrot(:,J)` 是作用在塔架单元 `J` 上的水动力和水动弯矩。 + * `RtHSdat%LinAccETt(:,J)` 是塔架单元 `J` 的线性加速度,用于计算非线性惯性力项(包括重力)。 + * `TmpVec1` 包含了塔架单元的重力、非线性惯性力以及水动力。 + * `TmpVec3` 包含了水动弯矩。 + * 这里还包含了水动力学项 `[C(q,t)]HydroT` 和 `{-f(qd,q,t)}HydroT`,这在[[Tower]]笔记中没有直接列出,但在OpenFAST中是塔架受力的一部分。 + +4. **塔架弹性力和阻尼力**: + 这部分对应于[[Tower]]笔记中公式 (16) 和 (18) 中的弹性力和阻尼力项。 + ```fortran + IF ( p%DOF_Flag(DOF_TFA1) ) THEN + AugMat( DOF_TFA1,p%NAug) = AugMat(DOF_TFA1,p%NAug) & + - p%KTFA(1,1)*x%QT( DOF_TFA1) - p%KTFA(1,2)*x%QT( DOF_TFA2) & ! + - p%CTFA(1,1)*x%QDT(DOF_TFA1) - p%CTFA(1,2)*x%QDT(DOF_TFA2) + ENDIF + IF ( p%DOF_Flag(DOF_TSS1) ) THEN + AugMat( DOF_TSS1,p%NAug) = AugMat(DOF_TSS1,p%NAug) & + - p%KTSS(1,1)*x%QT( DOF_TSS1) - p%KTSS(1,2)*x%QT( DOF_TSS2) & ! {-f(qd,q,t)}ElasticT + {-f(qd,q,t)}DampT + - p%CTSS(1,1)*x%QDT(DOF_TSS1) - p%CTSS(1,2)*x%QDT(DOF_TSS2) + ENDIF + IF ( p%DOF_Flag(DOF_TFA2) ) THEN + AugMat( DOF_TFA2,p%NAug) = AugMat(DOF_TFA2,p%NAug) & + - p%KTFA(2,1)*x%QT( DOF_TFA1) - p%KTFA(2,2)*x%QT( DOF_TFA2) & ! + - p%CTFA(2,1)*x%QDT(DOF_TFA1) - p%CTFA(2,2)*x%QDT(DOF_TFA2) + ENDIF + IF ( p%DOF_Flag(DOF_TSS2) ) THEN + AugMat( DOF_TSS2,p%NAug) = AugMat(DOF_TSS2,p%NAug) & + - p%KTSS(2,1)*x%QT( DOF_TSS1) - p%KTSS(2,2)*x%QT( DOF_TSS2) & ! + - p%CTSS(2,1)*x%QDT(DOF_TSS1) - p%CTSS(2,2)*x%QDT(DOF_TSS2) + ENDIF + ``` + * `p%DOF_Flag(DOF_TFA1)` 等检查塔架前后 (TFA) 和侧向 (TSS) 模态的自由度是否启用。 + * `p%KTFA`, `p%KTSS` 是塔架的广义刚度矩阵,对应于[[Tower]]笔记中的 $k_{ij}^{'TFA}$ 和 $k_{ij}^{'TSS}$。 + * `p%CTFA`, `p%CTSS` 是塔架的广义阻尼矩阵,对应于[[Tower]]笔记中阻尼力公式中的系数。 + * `x%QT` 是广义坐标 $q$,`x%QDT` 是广义速度 $\dot{q}$。 + * 这些项直接添加到 `AugMat` 的力向量列 (`p%NAug`) 中。 + +5. **其他自由度与塔架的耦合**: + 在 `FillAugMat` 的后续部分,还有许多 `IF ( p%DOF_Flag (...) ) THEN ... ENDIF` 块,它们处理不同自由度(如平台运动 DOF_Sg, DOF_Sw, DOF_Hv, DOF_R, DOF_P, DOF_Y,以及偏航 DOF_Yaw 等)与塔架的耦合。这些耦合项通过 `DOT_PRODUCT` 广义速度偏导数和广义力/力矩偏导数来计算,并添加到 `AugMat` 中。例如: + ```fortran + IF ( p%DOF_Flag (DOF_TFA1) ) THEN + DO I = p%DOFs%Diag(DOF_TFA1),p%DOFs%NActvDOF ! Loop through all active (enabled) DOFs on or below the diagonal + AugMat(p%DOFs%SrtPS(I),DOF_TFA1) = AugMat(p%DOFs%SrtPS(I),DOF_TFA1) & + - DOT_PRODUCT( RtHSdat%PLinVelEO(DOF_TFA1,0,:), & + RtHSdat%PFrcONcRt(:,p%DOFs%SrtPS(I)) ) & ! [C(q,t)]N + [C(q,t)]R + [C(q,t)]G + [C(q,t)]H + [C(q,t)]B + [C(q,t)]A + - DOT_PRODUCT( RtHSdat%PAngVelEB(DOF_TFA1,0,:), & + RtHSdat%PMomBNcRt(:,p%DOFs%SrtPS(I)) ) + ENDDO + ! ... (力向量项) + ENDIF + ``` + 这部分代码计算了塔架自由度 (DOF_TFA1) 与其他自由度之间的耦合质量项和力项。`RtHSdat%PLinVelEO` 和 `RtHSdat%PAngVelEB` 是不同参考点(O点,B点)的广义速度偏导数,`RtHSdat%PFrcONcRt` 和 `RtHSdat%PMomBNcRt` 是广义力/力矩的偏导数。 + +6. **对称性填充**: + ```fortran + DO L = 2,p%DOFs%NActvDOF ! Loop through all active (enabled) DOFs above the diagonal (columns) + DO I = 1,L-1 ! Loop through all active (enabled) DOFs above the diagonal (rows) + AugMat(p%DOFs%SrtPS(I),p%DOFs%SrtPS(L)) = AugMat(p%DOFs%SrtPS(L),p%DOFs%SrtPS(I)) + ENDDO ! I - All active (enabled) DOFs above the diagonal (rows) + ENDDO ! L - All active (enabled) DOFs above the diagonal (columns) + ``` + 由于质量矩阵在添加齿轮箱摩擦项之前是(或近似)对称的,这部分代码通过镜像对角线以下的元素来填充对角线以上的元素,从而提高计算效率。 + +### 总结 + +[[Tower]]笔记提供了塔架动力学建模的理论基础,通过凯恩方程推导了塔架在各种载荷下的广义力表达式。这些表达式包含了塔架的惯性、弹性、阻尼、重力和气动特性。 + +[[FillAugmat]]子程序则将这些理论公式转化为实际的数值计算。它通过遍历塔架的离散化单元和自由度,计算出对应的广义质量矩阵项和广义力向量项,并将它们组装到增广矩阵 `AugMat` 中。这个过程涉及对广义速度偏导数、广义加速度、质量密度、刚度、阻尼系数以及外部载荷(如重力、气动力、水动力)的数值积分和点积运算。最终形成的 `AugMat` 矩阵是求解整个风力机系统动力学方程的关键输入。 +[Timestamp: 2026/01/12 11:25:40] + +**user**: [[Tower]][[CalculateForcesMoments]]结合理论和代码,解释塔架部分是如何计算的 +[Timestamp: 2026/01/12 16:16:07] + +**ai**: 好的,我们来结合[[Tower]]笔记中的理论和[[CalculateForcesMoments]]子程序中的代码,解释塔架部分是如何计算的。 + +`CalculateForcesMoments` 子程序的主要目的是计算风力机各个部件(包括塔架)上的力和力矩,并将这些结果存储在 `RtHSdat` 结构体中。这些力和力矩包括广义惯性力、弹性力、阻尼力、重力、气动力和水动力等。这些计算结果随后会被 `FillAugmat` 子程序用来构建系统的增广矩阵。 + +### 理论回顾 (来自 [[Tower]] 笔记) + +[[Tower]]笔记详细推导了塔架的广义惯性力、弹性力、阻尼力、重力和气动力。这些力通常表示为对广义坐标或广义速度的函数,并且在动力学方程中作为力向量的一部分。 + +* **广义惯性力 ($F_r^* \Big|_T$)**: 包含质量项和非线性惯性力项。在 `CalculateForcesMoments` 中,主要计算的是非线性惯性力项,即与加速度无关的速度相关项。 + * 非线性惯性力项: + $$ + \left\{ - f(\dot{q},q,t) \right\} \Big|_T (Row) = - \int_0^{TwrFlexL} \mu^T (h) {}^E \mathbf{v}_{Row}^T (h) \cdot \left( \sum_{i=4}^{10} \frac{d}{dt} \left[ {}^E \mathbf{v}_i^T (h) \right] \dot{q}_i \right) dh - YawBrMass {}^E \mathbf{v}_{Row}^O \cdot \left[ \sum_{i=4}^{10} \frac{d}{dt} \left( {}^E \mathbf{v}_i^O \right) \dot{q}_i \right] \quad (Row = 1,2,\ldots,10)\tag{4} + $$ +* **广义弹性力 ($F_{r \Big| ElasticT}$)**: 与广义坐标 $q_r$ 相关。 + $$ + \{-f(\dot{q},q,t)\}|_{\text{Elastic}T} = \begin{Bmatrix} + \vdots \\ + -k_{11}^{'TFA} q_{TFA1} - k_{12}^{'TFA} q_{TFA2} \\ + \vdots + \end{Bmatrix}\tag{16} + $$ +* **广义阻尼力 ($F_r |_{\text{Damp}T}$)**: 与广义速度 $\dot{q}_r$ 相关。 + $$ + \{-f(\dot{q},q,t)\}|_{\text{Damp}T} = \begin{Bmatrix} + \vdots \\ + - \frac{\zeta_1^{TFA} k_{11}^{'TFA}}{\pi f_1^{'TFA}} \dot{q}_{TFA1} - \frac{\zeta_2^{TFA} k_{12}^{'TFA}}{\pi f_2^{'TFA}} \dot{q}_{TFA2} \\ + \vdots + \end{Bmatrix}\tag{18} + $$ +* **广义重力 ($F_r |_{\text{Grav}T}$)**: + $$ + \{-f(\dot{q},q,t)\}|_{\text{Grav}T} (\text{Row}) = - \int_{0}^{\text{TwrFlexL}} \! \mu^T(h) g {}^E \mathbf{v}_{\text{Row}}^T(h) \cdot \mathbf{z}_2 \, dh - \text{YawBrMass} \cdot g {}^E \mathbf{v}_{\text{Row}}^O \cdot \mathbf{z}_2 \quad (Row=3,4,...,10)\tag{21} + $$ +* **广义气动力 ($F_r |_{\text{Aero}T}$)**: + $$ + \{-f(\dot{q},q,t)\}|_{\text{Aero}T} (\text{Row}) = \int_{0}^{\text{TwrFlexL}} \! \left[ {}^E \mathbf{v}_{\text{Row}}^T(h) \cdot \mathbf{F}_{\text{Aero}T}^T(h) + {}^E \boldsymbol{\omega}_{\text{Row}}^F(h) \cdot \mathbf{M}_{\text{Aero}T}^F(h) \right] dh \quad (Row=1,2,...,10)\tag{24} + $$ + +### 代码实现 (来自 [[CalculateForcesMoments]] 子程序) + +`CalculateForcesMoments` 子程序计算并存储了各种“部分力”和“总力”,这些力是用于后续组装增广矩阵的中间结果。对于塔架部分,主要涉及以下几个关键计算: + +1. **塔架单元上的水动力和水动弯矩 (PFTHydro, PMFHydro, FTHydrot, MFHydrot)**: + 这部分计算了作用在塔架每个离散化单元上的水动力和水动弯矩。这些力不仅包括水动力学贡献,还可能包括基础刚度、阻尼或系泊线恢复力等。 + * **理论**: 这部分在[[Tower]]笔记中没有直接的公式,但在OpenFAST中,水动力学是塔架受力的重要组成部分,尤其对于浮式风力机。它通常通过附加质量、阻尼和恢复力矩阵来建模。 + * **代码**: + ```fortran + DO J=1,p%TwrNodes + RtHSdat%PFTHydro(:,J,:) = 0.0 + RtHSdat%PMFHydro(:,J,:) = 0.0 + DO I = 1,p%DOFs%NPTE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tower + ! ... (计算 PFTHydro 和 PMFHydro,涉及 u%TwrAddedMass 和广义速度偏导数) + END DO + END DO + + DO J=1,p%TwrNodes + ! ... (计算 FTHydrot 和 MFHydrot,涉及 u%TowerPtLoads%Force/Moment, u%TwrAddedMass 和线/角加速度) + END DO + ``` + * `p%TwrNodes` 是塔架的节点数量。 + * `u%TwrAddedMass` 是塔架的附加质量矩阵,用于计算水动力学惯性力。 + * `RtHSdat%PLinVelET` 和 `RtHSdat%PAngVelEF` 是塔架单元的广义线速度和角速度的偏导数,用于计算与广义加速度相关的部分力。 + * `RtHSdat%LinAccETt` 和 `RtHSdat%AngAccEFt` 是塔架单元的线加速度和角加速度,用于计算与广义速度相关的力(科里奥利力、离心力)以及重力。 + * `u%TowerPtLoads%Force/Moment` 是外部施加在塔架上的点载荷。 + * `PFTHydro` 和 `PMFHydro` 存储的是与广义加速度相关的部分力/力矩,用于构建质量矩阵。 + * `FTHydrot` 和 `MFHydrot` 存储的是与广义加速度无关的力/力矩(包括重力、水动力阻尼、恢复力、外部载荷以及非线性惯性力),用于构建力向量。 + +2. **偏航轴承处的力和力矩 (PFrcT0Trb, PMomX0Trb, FrcT0Trbt, MomX0Trbt)**: + 这部分计算了在塔架底部(点 T(0))的力和力矩,包括来自偏航轴承以上所有部件(转子、机舱、尾翼等)以及偏航轴承自身的贡献。 + * **理论**: 这对应于[[Tower]]笔记中公式 (19) 和 (21) 中与 `YawBrMass` 相关的项,以及来自上部结构的传递载荷。 + * **代码**: + ```fortran + ! ... (初始化 PFrcT0Trb 和 PMomX0Trb 为来自上部结构 (PFrcONcRt, PMomBNcRt) 的贡献) + RtHSdat%PFrcT0Trb = RtHSdat%PFrcONcRt + RtHSdat%PMomX0Trb = RtHSdat%PMomX0Trb + + DO I = 1,p%DOFs%NPTE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the yaw bearing center of mass (point O) + TmpVec1 = -p%YawBrMass*RtHSdat%PLinVelEO(p%DOFs%PTE(I),0,:) ! The portion of PFrcT0Trb associated with the YawBrMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0O, TmpVec1 ) ! The portion of PMomX0Trb associated with the YawBrMass + RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I) ) = RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I) ) + TmpVec1 + RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I) ) = RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I) ) + TmpVec2 + END DO + + TmpVec1 = -p%YawBrMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEOt ) ! The portion of FrcT0Trbt associated with the YawBrMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0O, TmpVec1 ) ! The portion of MomX0Trbt associated with the YawBrMass + TmpVec3 = CROSS_PRODUCT( RtHSdat%rT0O, RtHSdat%FrcONcRtt ) ! The portion of MomX0Trbt associated with the FrcONcRtt + RtHSdat%FrcT0Trbt = RtHSdat%FrcONcRtt + TmpVec1 + RtHSdat%MomX0Trbt = RtHSdat%MomBNcRtt + TmpVec2 + TmpVec3 + + DO J=1,p%TwrNodes + DO I = 1,p%DOFs%NPTE + TmpVec1 = RtHSdat%PFTHydro(:,J,p%DOFs%PTE(I))*abs(p%DHNodes(J)) - p%TElmntMass(J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,:) ! The portion of PFrcT0Trb associated with tower element J + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0T(:,J), TmpVec1 ) ! The portion of PMomX0Trb associated with tower element J + TmpVec3 = RtHSdat%PMFHydro(:,J,p%DOFs%PTE(I))*abs(p%DHNodes(J)) ! The added moment applied at tower element J + RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I)) = RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I)) + TmpVec1 + RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I)) = RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I)) + TmpVec2 + TmpVec3 + END DO + + TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*abs(p%DHNodes(J)) & + - p%TElmntMass(J)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccETt(:,J) ) ! The portion of FrcT0Trbt associated with tower element J + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0T(:,J), TmpVec1 ) ! The portion of MomX0Trbt associated with tower element J + TmpVec3 = ( RtHSdat%MFHydrot(:,J) )*abs(p%DHNodes(J)) ! The external moment applied to tower element J + RtHSdat%FrcT0Trbt = RtHSdat%FrcT0Trbt + TmpVec1 + RtHSdat%MomX0Trbt = RtHSdat%MomX0Trbt + TmpVec2 + TmpVec3 + END DO + ``` + * `p%YawBrMass` 是偏航轴承质量。 + * `RtHSdat%PLinVelEO` 是偏航轴承点 O 的广义线速度偏导数。 + * `RtHSdat%LinAccEOt` 是偏航轴承点 O 的线性加速度。 + * `RtHSdat%rT0O` 是从塔基 (T0) 到偏航轴承 (O) 的位置向量。 + * `RtHSdat%rT0T` 是从塔基 (T0) 到塔架单元 (T) 的位置向量。 + * `PFrcT0Trb` 和 `PMomX0Trb` 累加了来自偏航轴承和塔架单元的与广义加速度相关的部分力/力矩。 + * `FrcT0Trbt` 和 `MomX0Trbt` 累加了来自偏航轴承和塔架单元的与广义加速度无关的力/力矩(包括重力、水动力、气动力等)。 + +3. **平台参考点处的力和力矩 (PFrcZAll, PMomXAll, FrcZAllt, MomXAllt)**: + 这部分计算了在平台参考点 (Z) 处的总力和力矩,包括来自整个风力机(包括塔架)和平台自身的贡献。 + * **理论**: 这是整个系统在平台参考点处的总广义力和力矩。 + * **代码**: + ```fortran + RtHSdat%PFrcZAll = RtHSdat%PFrcT0Trb + RtHSdat%PMomXAll = RtHSdat%PFrcT0Trb + + DO I = 1,p%DOFs%NActvDOF + TmpVec = CROSS_PRODUCT( RtHSdat%rZT0, RtHSdat%PFrcT0Trb(:,p%DOFs%SrtPS(I)) ) + RtHSdat%PMomXAll(:,p%DOFs%SrtPS(I)) = RtHSdat%PMomXAll(:,p%DOFs%SrtPS(I)) + TmpVec + END DO + + DO I = 1,p%DOFs%NPYE + TmpVec1 = -p%PtfmMass*RtHSdat%PLinVelEY(p%DOFs%PYE(I),0,:) + TmpVec2 = CROSS_PRODUCT( RtHSdat%rZY , TmpVec1 ) + RtHSdat%PFrcZAll(:,p%DOFs%PYE(I)) = RtHSdat%PFrcZAll(:,p%DOFs%PYE(I) ) + RtHSdat%PFZHydro(p%DOFs%PYE(I),:) + TmpVec1 + RtHSdat%PMomXAll(:,p%DOFs%PYE(I)) = RtHSdat%PMomXAll(:,p%DOFs%PYE(I) ) + RtHSdat%PMXHydro(p%DOFs%PYE(I),:) + TmpVec2 & + - p%PtfmRIner*CoordSys%a1*DOT_PRODUCT( CoordSys%a1, RtHSdat%PAngVelEX(p%DOFs%PYE(I),0,:) ) & + - p%PtfmYIner*CoordSys%a2*DOT_PRODUCT( CoordSys%a2, RtHSdat%PAngVelEX(p%DOFs%PYE(I),0,:) ) & + - p%PtfmPIner*CoordSys%a3*DOT_PRODUCT( CoordSys%a3, RtHSdat%PAngVelEX(p%DOFs%PYE(I),0,:) ) + END DO + + TmpVec1 = -p%PtfmMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEYt ) + TmpVec2 = CROSS_PRODUCT( RtHSdat%rZY , TmpVec1 ) + TmpVec3 = CROSS_PRODUCT( RtHSdat%rZT0 , RtHSdat%FrcT0Trbt ) + TmpVec = p%PtfmRIner*CoordSys%a1*DOT_PRODUCT( CoordSys%a1, RtHSdat%AngVelEX ) & + + p%PtfmYIner*CoordSys%a2*DOT_PRODUCT( CoordSys%a2, RtHSdat%AngVelEX ) & + + p%PtfmPIner*CoordSys%a3*DOT_PRODUCT( CoordSys%a3, RtHSdat%AngVelEX ) + TmpVec4 = CROSS_PRODUCT( -RtHSdat%AngVelEX, TmpVec ) + + RtHSdat%FrcZAllt = RtHSdat%FrcT0Trbt + RtHSdat%FZHydrot + TmpVec1 + RtHSdat%MomXAllt = RtHSdat%MomX0Trbt + RtHSdat%MXHydrot + TmpVec2 + TmpVec3 + TmpVec4 + ``` + * `RtHSdat%rZT0` 是从平台参考点 (Z) 到塔基 (T0) 的位置向量。 + * `p%PtfmMass` 是平台质量。 + * `RtHSdat%PLinVelEY` 是平台质心 (Y) 的广义线速度偏导数。 + * `RtHSdat%LinAccEYt` 是平台质心 (Y) 的线性加速度。 + * `PFrcZAll` 和 `PMomXAll` 累加了来自塔架和平台自身的与广义加速度相关的部分力/力矩。 + * `FrcZAllt` 和 `MomXAllt` 累加了来自塔架和平台自身的与广义加速度无关的力/力矩。 + +### 总结 + +`CalculateForcesMoments` 子程序是OpenFAST动力学计算中的一个核心部分,它根据当前系统的状态(广义坐标 `x%QT` 和广义速度 `x%QDT`)、参数 `p`、坐标系信息 `CoordSys` 和外部输入 `u`,计算出作用在风力机各个部件上的力和力矩。 + +对于塔架部分,它主要完成了以下工作: +1. **计算塔架单元上的水动力和水动弯矩**:这包括与广义加速度相关的部分(`PFTHydro`, `PMFHydro`)和与广义加速度无关的部分(`FTHydrot`, `MFHydrot`),后者包含了重力、水动力阻尼、恢复力以及外部点载荷和非线性惯性力。 +2. **自下而上累加力矩**:从叶片、轮毂、机舱、尾翼等部件开始,逐步向上累加力和力矩,直到塔基 (T0) 和平台参考点 (Z)。这个过程利用了力矩的传递原理,将各个部件的力和力矩转换到共同的参考点。 +3. **区分部分力/力矩和总力/力矩**: + * 以 `PFrc...` 和 `PMom...` 开头的变量存储的是“部分力”和“部分力矩”,它们是广义加速度的系数,用于构建质量矩阵。 + * 以 `Frc...t` 和 `Mom...t` 结尾的变量存储的是“总力”和“总力矩”,它们是与广义加速度无关的项,用于构建力向量。 + +虽然[[Tower]]笔记提供了塔架广义力的理论表达式,但`CalculateForcesMoments`子程序通过数值方法,结合了OpenFAST中更全面的物理模型(如水动力学、外部载荷等),计算出这些力和力矩的具体数值,为后续的动力学方程求解提供了必要的输入。 +[Timestamp: 2026/01/12 16:16:33] + +**user**: [[Tower]][[CalculateAngularPosVelPAcc]]结合理论和代码,解释塔架部分是如何计算的 +[Timestamp: 2026/01/12 16:20:19] + +**ai**: `CalculateAngularPosVelPAcc` 子程序在OpenFAST动力学模型中扮演着关键角色,它负责计算风力机各个部件(包括塔架)的角位置、角速度以及部分角加速度。这些运动学量是后续计算广义力和组装动力学方程的基础。 + +### 理论回顾 (来自 [[Tower]] 笔记) + +[[Tower]]笔记中,塔架被视为一个柔性体,其运动通过广义坐标 $q_i$ 及其时间导数 $\dot{q}_i$ 和 $\ddot{q}_i$ 来描述。塔架的柔性变形通过模态叠加原理来表示,即塔架上任意一点的位移、速度和加速度是刚体运动和各个柔性模态贡献的叠加。 + +* **广义速度和加速度**: 笔记中提到了塔架上点 T 的广义速度 ${}^E \mathbf{v}_r^T (h)$ 和广义加速度 ${}^E \mathbf{a}^T (h)$。这些向量包含了线性和角运动分量,并且与广义坐标及其导数相关。 +* **非线性惯性力**: 公式 (4) 中包含了 $\frac{d}{dt} \left( {}^E \mathbf{v}_i^T (h) \right) \dot{q}_i$ 这样的项,这表示了科里奥利力和离心力等非线性惯性效应,它们依赖于广义速度和广义速度的偏导数。为了计算这些项,需要知道部分角速度及其时间导数。 + +### 代码实现 (来自 [[CalculateAngularPosVelPAcc]] 子程序) + +`CalculateAngularPosVelPAcc` 子程序通过自下而上的方式(从平台到塔架,再到机舱、轮毂和叶片)计算各个部件的运动学量。我们重点关注塔架相关的计算部分。 + +在代码中,塔架的计算位于 `!............... ! tower values: !...............` 注释块下。 + +1. **塔架单元的部分角速度 (`RtHSdat%PAngVelEF (J, :,0,:)`)**: + 这表示塔架上第 `J` 个节点(或单元,用 `F` 表示)在惯性坐标系 `E` 中的部分角速度。`0` 表示这是部分角速度本身(0阶导数)。 + ```fortran + RtHSdat%PAngVelEF (J, :,0,:) = RtHSdat%PAngVelEX(:,0,:) + RtHSdat%PAngVelEF (J,DOF_TFA1,0,:) = -p%TwrFASF(1,J,1)*CoordSys%a3 + RtHSdat%PAngVelEF (J,DOF_TSS1,0,:) = p%TwrSSSF(1,J,1)*CoordSys%a1 + RtHSdat%PAngVelEF (J,DOF_TFA2,0,:) = -p%TwrFASF(2,J,1)*CoordSys%a3 + RtHSdat%PAngVelEF (J,DOF_TSS2,0,:) = p%TwrSSSF(2,J,1)*CoordSys%a1 + ``` + * `RtHSdat%PAngVelEX(:,0,:)`:首先,塔架的部分角速度继承了平台(`X`)的部分角速度。这反映了塔架的刚体运动部分。 + * `p%TwrFASF` 和 `p%TwrSSSF`:这些是塔架在前后 (TFA) 和侧向 (TSS) 方向上的模态形状函数(Shape Functions)。`p%TwrFASF(1,J,1)` 表示第一个前后弯曲模态在第 `J` 个塔架节点处的形状函数值。 + * `CoordSys%a3` 和 `CoordSys%a1`:这些是机舱坐标系中的单位向量,分别代表了塔架前后弯曲和侧向弯曲的方向。 + * 通过将模态形状函数乘以相应的方向向量,并与平台的部分角速度叠加,计算出塔架每个柔性自由度对部分角速度的贡献。这直接体现了[[Tower]]笔记中柔性体运动的模态叠加原理。 + +2. **塔架单元的部分角速度的1阶导数 (`RtHSdat%PAngVelEF (J, :,1,:)`)**: + 这表示塔架上第 `J` 个节点的部分角速度的时间导数(1阶导数),即部分角加速度。 + ```fortran + RtHSdat%PAngVelEF (J, :,1,:) = RtHSdat%PAngVelEX(:,1,:) + RtHSdat%PAngVelEF (J,DOF_TFA1,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TFA1,0,:) ) + RtHSdat%PAngVelEF (J,DOF_TSS1,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TSS1,0,:) ) + RtHSdat%PAngVelEF (J,DOF_TFA2,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TFA2,0,:) ) + RtHSdat%PAngVelEF (J,DOF_TSS2,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TSS2,0,:) ) + ``` + * `RtHSdat%PAngVelEX(:,1,:)`:首先,继承平台的部分角加速度。 + * `CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TFA1,0,:) )`:这部分计算了科里奥利项。根据运动学原理,一个向量在旋转坐标系中的时间导数包含一个相对导数项和一个科里奥利项($\boldsymbol{\omega} \times \mathbf{v}$)。在这里,`RtHSdat%AngVelEX` 是平台(惯性系中的刚体部分)的角速度,`RtHSdat%PAngVelEF(J,DOF_TFA1,0,:)` 是塔架柔性模态的部分角速度。这个叉乘项正是由于平台旋转引起的塔架柔性模态部分角速度的变化率。这与[[Tower]]笔记中公式 (4) 的 $\frac{d}{dt} \left( {}^E \mathbf{v}_i^T (h) \right)$ 项直接相关。 + +3. **塔架单元的总角速度 (`RtHSdat%AngVelEF (:,J)`)**: + 这是塔架上第 `J` 个节点在惯性坐标系 `E` 中的总角速度。 + ```fortran + RtHSdat%AngVelEF (:,J) = RtHSdat%AngVelEX + x%QDT(DOF_TFA1)*RtHSdat%PAngVelEF(J,DOF_TFA1,0,:) & + + x%QDT(DOF_TSS1)*RtHSdat%PAngVelEF(J,DOF_TSS1,0,:) & + + x%QDT(DOF_TFA2)*RtHSdat%PAngVelEF(J,DOF_TFA2,0,:) & + + x%QDT(DOF_TSS2)*RtHSdat%PAngVelEF(J,DOF_TSS2,0,:) + ``` + * `RtHSdat%AngVelEX`:平台在惯性系中的总角速度。 + * `x%QDT`:广义速度向量,例如 `x%QDT(DOF_TFA1)` 是第一个塔架前后弯曲模态的广义速度。 + * 通过将平台总角速度与每个塔架柔性模态的广义速度乘以其对应的部分角速度叠加,得到塔架节点的总角速度。这正是柔性体运动学中总速度的计算方式。 + +4. **塔架单元的相对角位置 (`RtHSdat%AngPosXF (:,J)`) 和总角位置 (`RtHSdat%AngPosEF (:,J)`)**: + * `RtHSdat%AngPosXF (:,J)`:表示塔架第 `J` 个节点相对于平台(或其刚体部分)的角位置。它通过将每个塔架柔性模态的广义位置 `x%QT` 乘以其对应的部分角速度(注意这里是部分角速度,而不是部分角位置,因为在小角度假设下,角位置的偏导数近似等于部分角速度)来计算。 + * `RtHSdat%AngPosEF (:,J)`:塔架第 `J` 个节点在惯性系中的总角位置,是平台总角位置 `RtHSdat%AngPosEX` 和相对角位置 `RtHSdat%AngPosXF` 的叠加。 + +5. **塔架单元的部分角加速度 (`RtHSdat%AngAccEFt(:,J)`)**: + 这表示塔架上第 `J` 个节点在惯性坐标系 `E` 中的部分角加速度,即不包含 $\ddot{q}_i$ 项的角加速度。这部分包含了科里奥利力和离心力等非线性惯性效应。 + ```fortran + RtHSdat%AngAccEFt(:,J) = RtHSdat%AngAccEXt + x%QDT(DOF_TFA1)*RtHSdat%PAngVelEF(J,DOF_TFA1,1,:) & + + x%QDT(DOF_TSS1)*RtHSdat%PAngVelEF(J,DOF_TSS1,1,:) & + + x%QDT(DOF_TFA2)*RtHSdat%PAngVelEF(J,DOF_TFA2,1,:) & + + x%QDT(DOF_TSS2)*RtHSdat%PAngVelEF(J,DOF_TSS2,1,:) + ``` + * `RtHSdat%AngAccEXt`:平台在惯性系中的部分角加速度。 + * 通过将每个塔架柔性模态的广义速度 `x%QDT` 乘以其对应的部分角速度的1阶导数 (`RtHSdat%PAngVelEF(J,DOF_TFA1,1,:)`),并与平台的部分角加速度叠加,得到塔架节点的总部分角加速度。这直接对应于[[Tower]]笔记中公式 (4) 的非线性惯性力项。 + +### 总结 + +`CalculateAngularPosVelPAcc` 子程序通过以下方式计算塔架的运动学量: + +1. **模态叠加**: 利用塔架的模态形状函数 (`p%TwrFASF`, `p%TwrSSSF`) 和广义坐标 (`x%QT`, `x%QDT`) 来描述塔架的柔性变形。 +2. **分层计算**: 从平台开始,逐级向上计算各个部件的运动学量,塔架的运动学量是在平台运动的基础上叠加其自身柔性变形的贡献。 +3. **偏导数和时间导数**: 精确计算了部分角速度 (`PAngVelEF (J, :,0,:)`) 及其时间导数 (`PAngVelEF (J, :,1,:)`)。这些导数对于正确捕捉科里奥利力和离心力等非线性惯性效应至关重要,它们是[[Tower]]笔记中广义力公式(特别是惯性力部分)的直接输入。 +4. **总运动学量**: 结合刚体运动和柔性变形的贡献,计算出塔架节点的总角速度 (`AngVelEF`) 和总角位置 (`AngPosEF`)。 + +这些计算结果(特别是部分角速度及其导数,以及总角速度和部分角加速度)被存储在 `RtHSdat` 结构体中,供后续的 `CalculateForcesMoments` 和 `FillAugmat` 等子程序使用,以构建完整的动力学方程。 +[Timestamp: 2026/01/12 16:20:52] + +**user**: [[Tower]][[CalculatePositions]]结合理论和代码,解释塔架部分是如何计算的 +[Timestamp: 2026/01/12 16:25:27] + +**ai**: 好的,我们来结合[[Tower]]笔记中的理论和[[CalculatePositions]]子程序中的代码,解释塔架部分是如何计算的。 + +`CalculatePositions` 子程序在OpenFAST动力学模型中负责计算风力机各个部件(包括塔架)在惯性坐标系中的位置向量。这些位置信息是后续计算速度、加速度以及广义力和力矩的基础。 + +### 理论回顾 (来自 [[Tower]] 笔记) + +[[Tower]]笔记中,塔架被视为一个柔性体,其变形通过模态叠加原理来描述。塔架上任意一点的位移是刚体运动和各个柔性模态贡献的叠加。 + +* **广义坐标 ($q_i$)**: 笔记中提到了塔架的前后 (TFA) 和侧向 (TSS) 弯曲模态的广义坐标 $q_{TFA1}, q_{TFA2}, q_{TSS1}, q_{TSS2}$。这些广义坐标代表了塔架柔性变形的程度。 +* **模态形状函数 ($\phi_i^{TFA}(h), \phi_i^{TSS}(h)$)**: 塔架的柔性变形通常通过模态形状函数来描述,这些函数定义了塔架沿其高度 $h$ 的变形模式。 +* **轴向缩短效应 (Axial Shortening)**: 柔性体的弯曲变形会导致其轴向长度的微小缩短,这是一种非线性效应,通常通过二次项来近似。 + +### 代码实现 (来自 [[CalculatePositions]] 子程序) + +`CalculatePositions` 子程序通过自下而上的方式(从平台到塔架,再到机舱、轮毂和叶片)计算各个部件的位置向量。我们重点关注塔架相关的计算部分。 + +1. **塔顶/底板的位置向量 (`RtHSdat%rZO`)**: + 这部分计算了从平台参考点 (Z) 到塔顶/底板 (O) 的位置向量。这个向量包含了塔架的刚体高度以及由于塔架柔性变形引起的水平位移和轴向缩短。 + ```fortran + RtHSdat%rZO = ( x%QT(DOF_TFA1) + x%QT(DOF_TFA2) )*CoordSys%a1 & ! Position vector from platform reference (point Z) to tower-top / base plate (point O). + + ( p%RefTwrHt - 0.5*( p%AxRedTFA(1,1,p%TTopNode)*x%QT(DOF_TFA1)*x%QT(DOF_TFA1) & + + p%AxRedTFA(2,2,p%TTopNode)*x%QT(DOF_TFA2)*x%QT(DOF_TFA2) & + + 2.0*p%AxRedTFA(1,2,p%TTopNode)*x%QT(DOF_TFA1)*x%QT(DOF_TFA2) & + + p%AxRedTSS(1,1,p%TTopNode)*x%QT(DOF_TSS1)*x%QT(DOF_TSS1) & + + p%AxRedTSS(2,2,p%TTopNode)*x%QT(DOF_TSS2)*x%QT(DOF_TSS2) & + + 2.0*p%AxRedTSS(1,2,p%TTopNode)*x%QT(DOF_TSS1)*x%QT(DOF_TSS2) ) )*CoordSys%a2 & + + ( x%QT(DOF_TSS1) + x%QT(DOF_TSS2) )*CoordSys%a3 + ``` + * `x%QT(DOF_TFA1)` 和 `x%QT(DOF_TFA2)`:塔架前后弯曲的两个模态的广义坐标。它们乘以 `CoordSys%a1`(机舱坐标系中的 x 方向单位向量)表示塔顶在前后方向的位移。 + * `x%QT(DOF_TSS1)` 和 `x%QT(DOF_TSS2)`:塔架侧向弯曲的两个模态的广义坐标。它们乘以 `CoordSys%a3`(机舱坐标系中的 z 方向单位向量,在OpenFAST中通常表示侧向)表示塔顶在侧向的位移。 + * `p%RefTwrHt`:塔架的参考高度。 + * `p%AxRedTFA` 和 `p%AxRedTSS`:这些是轴向缩短系数。当塔架弯曲时,其轴向长度会略微缩短。这部分通过广义坐标的二次项来近似,并乘以 `0.5`。这个缩短量从 `p%RefTwrHt` 中减去,表示塔顶在垂直方向(`CoordSys%a2`,机舱坐标系中的 y 方向单位向量,通常表示垂直)的实际高度。 + * `p%TTopNode`:表示塔顶所在的节点索引。 + +2. **塔基到塔顶的位置向量 (`RtHSdat%rT0O`)**: + ```fortran + RtHSdat%rT0O = RtHSdat%rZO - RtHSdat%rZT0 ! Position vector from the tower base (point T(0)) to tower-top / base plate (point O). + ``` + * `RtHSdat%rZT0` 是从平台参考点 (Z) 到塔基 (T(0)) 的位置向量,它是一个常数,表示塔架的刚体部分。 + * `RtHSdat%rT0O` 是塔基到塔顶的相对位置向量,它包含了塔架的柔性变形。 + +3. **塔架单元的位置向量 (`RtHSdat%rT0T`, `RtHSdat%rZT`, `RtHSdat%rT`)**: + 这部分计算了塔架每个离散化节点(或单元,用 `T` 表示)的位置。 + ```fortran + RtHSdat%rZT (:,0) = RtHSdat%rZT0 + DO J = 1,p%TwrNodes ! Loop through the tower nodes / elements + ! Calculate the position vector of the current node: + RtHSdat%rT0T(:,J) = ( p%TwrFASF(1,J,0)*x%QT(DOF_TFA1) + p%TwrFASF(2,J,0)*x%QT(DOF_TFA2) )*CoordSys%a1 & ! Position vector from base of flexible portion of tower (point T(0)) to current node (point T(J)). + + ( p%HNodes(J) - 0.5*( p%AxRedTFA(1,1,J)*x%QT(DOF_TFA1)*x%QT(DOF_TFA1) & + + p%AxRedTFA(2,2,J)*x%QT(DOF_TFA2)*x%QT(DOF_TFA2) & + + 2.0*p%AxRedTFA(1,2,J)*x%QT(DOF_TFA1)*x%QT(DOF_TFA2) & + + p%AxRedTSS(1,1,J)*x%QT(DOF_TSS1)*x%QT(DOF_TSS1) & + + p%AxRedTSS(2,2,J)*x%QT(DOF_TSS2)*x%QT(DOF_TSS2) & + + 2.0*p%AxRedTSS(1,2,J)*x%QT(DOF_TSS1)*x%QT(DOF_TSS2) ) )*CoordSys%a2 & + + ( p%TwrSSSF(1,J,0)*x%QT(DOF_TSS1) + p%TwrSSSF(2,J,0)*x%QT(DOF_TSS2) )*CoordSys%a3 + RtHSdat%rZT (:,J) = RtHSdat%rZT0 + RtHSdat%rT0T(:,J) ! Position vector from platform reference (point Z) to the current node (point T(HNodes(J)). + RtHSdat%rT(:,J) = RtHSdat%rZ + RtHSdat%rZT (:,J) ! Position vector from inertial frame origin to the current node (point T(HNodes(J)). + END DO + ``` + * `p%TwrNodes`:塔架的节点数量。 + * `p%HNodes(J)`:第 `J` 个塔架节点在未变形状态下的高度。 + * `RtHSdat%rT0T(:,J)`:从塔基 (T(0)) 到第 `J` 个塔架节点 (T(J)) 的相对位置向量。其计算方式与 `RtHSdat%rZO` 类似,使用了塔架模态形状函数 (`p%TwrFASF`, `p%TwrSSSF`) 和轴向缩短系数 (`p%AxRedTFA`, `p%AxRedTSS`),但这些参数是针对每个节点 `J` 进行评估的。 + * `RtHSdat%rZT (:,J)`:从平台参考点 (Z) 到第 `J` 个塔架节点 (T(J)) 的相对位置向量,是 `RtHSdat%rZT0` 和 `RtHSdat%rT0T(:,J)` 的叠加。 + * `RtHSdat%rT(:,J)`:从惯性坐标系原点到第 `J` 个塔架节点 (T(J)) 的绝对位置向量,是平台在惯性系中的位置 `RtHSdat%rZ` 和相对位置 `RtHSdat%rZT (:,J)` 的叠加。 + +### 总结 + +`CalculatePositions` 子程序通过以下方式计算塔架的位置: + +1. **模态叠加**: 塔架的柔性变形(前后弯曲和侧向弯曲)通过其广义坐标 (`x%QT`) 和模态形状函数 (`p%TwrFASF`, `p%TwrSSSF`) 来表示。 +2. **轴向缩短效应**: 考虑了塔架弯曲引起的轴向长度缩短这一非线性效应,通过广义坐标的二次项来近似。 +3. **分层计算**: 从平台参考点开始,逐步计算塔顶和塔架各个节点在惯性坐标系中的位置。每个节点的绝对位置都是其上层部件的绝对位置加上自身相对于上层部件的相对位置。 +4. **存储结果**: 计算出的所有位置向量都存储在 `RtHSdat` 结构体中,供后续的运动学(速度、加速度)和动力学(力和力矩)计算使用。 + +这些位置向量是OpenFAST中进行精确动力学分析的基础,它们直接影响了广义速度、广义加速度的计算,进而影响了广义惯性力、重力、气动力和水动力等各项力的计算。 +[Timestamp: 2026/01/12 16:25:42] + +**user**: [[Tower]][[Coeff]]结合理论和代码,解释塔架部分是如何计算的 +[Timestamp: 2026/01/12 16:27:21] + +**ai**: `Coeff` 子程序在OpenFAST动力学模型中负责计算风力机各个部件(包括塔架)的各种系数和属性。这些计算通常在模拟开始时进行一次,以设置系统的基本物理参数。[[Tower]]笔记提供了塔架动力学建模的理论基础,而`Coeff`子程序则将这些理论概念转化为具体的数值计算。 + +### 理论回顾 (来自 [[Tower]] 笔记) + +[[Tower]]笔记详细推导了塔架的广义惯性力、弹性力、阻尼力、重力和气动力。这些力的计算依赖于以下关键参数: + +* **质量密度 ($\mu^T(h)$)**: 塔架沿高度的质量分布,用于计算广义质量。 + $$ + \mu^T (h) = AdjTwMa \cdot TMassDen(h)\tag{1} + $$ +* **广义质量 ($m_{ij}^{'TFA}$, $m_{ij}^{'TSS}$)**: 塔架在前后 (TFA) 和侧向 (TSS) 方向上的广义质量,通过质量密度和模态形状函数积分得到。 + $$ + m_{\ i j}^{\prime^{T F A}}=\int_{0}^{T w r F l e x L}\mu^{T}\left(h\right)\phi_{i}^{T F A}\left(h\right)\phi_{j}^{T F A}\left(h\right)d h\quad\left(i,j=1,2\right)\tag{13} + $$ +* **广义刚度 ($k_{ij}^{'TFA}$, $k_{ij}^{'TSS}$)**: 塔架在前后和侧向方向上的广义刚度,通过弯曲刚度 ($EI$) 和模态形状函数的二阶导数积分得到。 + $$ + k_{ij}^{'TFA} = \sqrt{FAStTunr(i) FAStTunr(j)} \int_0^{TwrFlexL} EI^{TFA}(h) \frac{d^2 \phi_i^{TFA}(h)}{dh^2} \frac{d^2 \phi_j^{TFA}(h)}{dh^2} dh \quad (i, j = 1,2)\tag{7} + $$ +* **固有频率 ($f_{i}^{'TFA}$, $f_{i}^{\prime T S S}$)**: 塔架的固有频率,由广义刚度和广义质量决定。 + $$ + f_{\;\;i}^{\;\prime^{T F A}}=\frac{1}{2\pi}\sqrt{\frac{k_{\;i i}^{\prime^{T F A}}}{m_{\;i i}^{\prime^{T F A}}}}\tag{12} + $$ +* **阻尼比 ($\zeta_{i}^{T F A}$, $\zeta_{i}^{T S S}$)**: 塔架的结构阻尼比,用于计算广义阻尼。 +* **模态形状函数 ($\phi_i^{TFA}(h)$, $\phi_i^{TSS}(h)$)**: 描述塔架柔性变形的函数,及其一阶和二阶导数。 +* **轴向缩短效应**: 塔架弯曲时引起的轴向长度缩短,这是一种非线性几何效应。 + +### 代码实现 (来自 [[Coeff]] 子程序) + +`Coeff` 子程序通过数值积分和参数设置来计算上述理论参数。以下是塔架部分的关键计算: + +1. **初始化塔架相关参数**: + ```fortran + p%TwrMass = 0.0 + p%KTFA = 0.0 + p%KTSS = 0.0 + KTFAGrav = 0.0 + KTSSGrav = 0.0 + ``` + 在计算开始前,塔架的总质量、广义刚度(前后和侧向)以及重力去刚化项都被初始化为零。 + +2. **计算塔顶总质量 (`p%TwrTpMass`)**: + ```fortran + p%TwrTpMass = p%RotMass + p%RFrlMass + p%BoomMass + p%TFinMass + p%NacMass + p%YawBrMass + ``` + 这计算了塔架顶部所有部件(转子、变桨结构、尾翼、机舱、偏航轴承等)的总质量。这个总质量在计算塔架的广义质量和固有频率时非常重要,因为它作为塔顶的集中质量效应。 + +3. **塔架单元质量和质量累加 (`p%TElmntMass`, `p%TwrMass`, `TMssAbvNd`)**: + 通过一个从塔顶向下遍历塔架节点的循环: + ```fortran + DO J = p%TwrNodes,1,-1 + p%TElmntMass(J) = p%MassT(J)*abs(p%DHNodes(J)) ! 塔架单元J的质量 + p%TwrMass = p%TwrMass + p%TElmntMass(J) ! 累加塔架总质量 + TMssAbvNd(J) = 0.5*p%TElmntMass(J) ! 塔架单元J的质量贡献 + IF ( J == p%TwrNodes ) THEN + TMssAbvNd(J) = TMssAbvNd(J) + p%TwrTpMass ! 最上层单元加上塔顶总质量 + ELSE + TMssAbvNd(J) = 0.5*p%TElmntMass(J+1) + TMssAbvNd(J) + TMssAbvNd(J+1) ! 累加其上方所有质量 + ENDIF + ENDDO + ``` + * `p%TElmntMass(J)`: 计算每个塔架单元的质量,对应于理论中的 $\mu^T(h)dh$。 + * `p%TwrMass`: 累加所有塔架单元的质量,得到柔性塔架的总质量。 + * `TMssAbvNd(J)`: 计算在节点 `J` 以上所有塔架单元和塔顶部件的总质量。这对于计算重力去刚化效应至关重要,因为重力载荷取决于其上方结构的质量。 + +4. **初始化广义塔架质量 (考虑塔顶质量)**: + ```fortran + DO I = 1,2 + MTFA(I,I) = p%TwrTpMass + MTSS(I,I) = p%TwrTpMass + ENDDO + ``` + 将塔顶总质量作为塔架广义质量矩阵对角线项的初始值,这反映了塔顶集中质量对塔架模态惯性的贡献。 + +5. **塔架模态形状函数 (`p%TwrFASF`, `p%TwrSSSF`)**: + 通过一个从塔基向上遍历塔架节点的循环,使用 `SHP` 函数计算塔架每个节点处的前后 (FAM) 和侧向 (SSM) 模态形状函数及其一阶和二阶导数。 + ```fortran + DO J = 1,p%TwrNodes + p%TwrFASF(1,J,2) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM1Sh(:), 2, ErrStat, ErrMsg ) ! 二阶导数 + p%TwrFASF(1,J,1) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM1Sh(:), 1, ErrStat, ErrMsg ) ! 一阶导数 + p%TwrFASF(1,J,0) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM1Sh(:), 0, ErrStat, ErrMsg ) ! 零阶导数 (形状函数本身) + ! ... (类似地计算 TwrFASF(2,J,...) 和 TwrSSSF(...,J,...) ) + ENDDO + ``` + 这些形状函数及其导数是计算广义质量、广义刚度和轴向缩短效应的基础,直接对应于理论中的 $\phi_i(h)$ 及其导数。 + +6. **广义质量积分 (`MTFA`, `MTSS`)**: + 在遍历塔架节点的循环中,累加每个单元的质量贡献。 + ```fortran + DO I = 1,2 + MTFA(I,I) = MTFA(I,I) + p%TElmntMass(J)*p%TwrFASF(I,J,0)**2 + MTSS(I,I) = MTSS(I,I) + p%TElmntMass(J)*p%TwrSSSF(I,J,0)**2 + ENDDO + ``` + 这实现了理论中广义质量积分的数值近似,即 $\sum \mu^T(h) \phi_i(h)^2 \Delta h$。 + +7. **广义刚度积分 (`p%KTFA`, `p%KTSS`)**: + 同样在循环中,累加每个单元的刚度贡献。 + ```fortran + ElStffFA = p%StiffTFA(J)*abs(p%DHNodes(J)) ! 塔架单元J的前后刚度 + ElStffSS = p%StiffTSS(J)*abs(p%DHNodes(J)) ! 塔架单元J的侧向刚度 + DO I = 1,2 + DO L = 1,2 + p%KTFA(I,L) = p%KTFA(I,L) + ElStffFA *p%TwrFASF(I,J,2)*p%TwrFASF(L,J,2) + p%KTSS(I,L) = p%KTSS(I,L) + ElStffSS *p%TwrSSSF(I,J,2)*p%TwrSSSF(L,J,2) + ENDDO + ENDDO + ``` + 这实现了理论中广义刚度积分的数值近似,即 $\sum EI(h) \frac{d^2 \phi_i(h)}{dh^2} \frac{d^2 \phi_j(h)}{dh^2} \Delta h$。 + +8. **重力去刚化刚度 (`KTFAGrav`, `KTSSGrav`)**: + ```fortran + ElmntStff = -TMssAbvNd(J)*abs(p%DHNodes(J))*p%Gravity ! 塔架单元J的重力刚度项 + DO I = 1,2 + KTFAGrav(I,I) = KTFAGrav(I,I) + ElmntStff*p%TwrFASF(I,J,1)**2 + KTSSGrav(I,I) = KTSSGrav(I,I) + ElmntStff*p%TwrSSSF(I,J,1)**2 + ENDDO + ``` + 这计算了重力去刚化效应引起的刚度项,它与上方质量和模态形状函数的一阶导数(斜率)的平方有关。 + +9. **塔架轴向缩短形状函数 (`p%AxRedTFA`, `p%AxRedTSS`)**: + ```fortran + DO I = 1,2 + DO L = 1,2 + AxRdTFA (I,L) = 0.5*p%DHNodes(J)*p%TwrFASF(I,J,1)*p%TwrFASF(L,J,1) + p%AxRedTFA(I,L,J) = AxRdTFA(I,L) + ! ... (类似地计算 AxRedTSS) + ENDDO + ENDDO + ``` + 这计算了塔架弯曲引起的轴向缩短系数,它与模态形状函数的一阶导数(斜率)的乘积有关。这些系数将在`CalculatePositions`子程序中用于计算塔架的实际位置。 + +10. **应用模态刚度调谐器**: + ```fortran + DO I = 1,2 + DO L = 1,2 + p%KTFA(I,L) = SQRT( InputFileData%FAStTunr(I)*InputFileData%FAStTunr(L) )*p%KTFA(I,L) + p%KTSS(I,L) = SQRT( InputFileData%SSStTunr(I)*InputFileData%SSStTunr(L) )*p%KTSS(I,L) + ENDDO + ENDDO + ``` + 这实现了[[Tower]]笔记中提到的刚度调谐功能,允许用户通过输入参数调整塔架的固有频率。 + +11. **计算塔架固有频率 (`p%FreqTFA`, `p%FreqTSS`)**: + ```fortran + DO I = 1,2 + p%FreqTFA(I,1) = Inv2Pi*SQRT( p%KTFA(I,I)/( MTFA(I,I) - p%TwrTpMass ) ) ! 不含重力去刚化和塔顶质量 + p%FreqTFA(I,2) = Inv2Pi*SQRT( ( p%KTFA(I,I) + KTFAGrav(I,I) )/MTFA(I,I) ) ! 含重力去刚化和塔顶质量 + ! ... (类似地计算 FreqTSS) + ENDDO + ``` + 这直接实现了理论中的固有频率公式 $f = \frac{1}{2\pi}\sqrt{\frac{k}{m}}$,并考虑了不同情况下(是否包含重力去刚化和塔顶质量)的频率。 + +12. **计算广义阻尼 (`p%CTFA`, `p%CTSS`)**: + ```fortran + DO I = 1,2 + DO L = 1,2 + p%CTFA(I,L) = ( 0.01*InputFileData%TwrFADmp(L) )*p%KTFA(I,L)/( Pi*p%FreqTFA(L,1) ) + p%CTSS(I,L) = ( 0.01*InputFileData%TwrSSDmp(L) )*p%KTSS(I,L)/( Pi*p%FreqTSS(L,1) ) + ENDDO + ENDDO + ``` + 这根据瑞利阻尼假设(阻尼与刚度成比例)计算广义阻尼系数,使用了输入的阻尼比和计算出的固有频率。这对应于[[Tower]]笔记中广义阻尼力公式的系数。 + +13. **计算塔架形状函数和轴向缩短函数在塔顶的值**: + 这部分与前面的循环类似,但专门针对塔顶节点,确保塔顶的形状函数和轴向缩短值被正确计算。 + +14. **计算总风力机质量 (`p%TurbMass`)**: + ```fortran + p%TurbMass = p%TwrTpMass + p%TwrMass + ``` + 将塔顶总质量和柔性塔架总质量相加,得到整个风力机的总质量。 + +### 总结 + +`Coeff` 子程序是OpenFAST中进行参数预处理的核心,它将用户在输入文件中定义的物理特性(如质量分布、刚度、模态形状函数等)转化为动力学模型所需的各种系数。对于塔架部分,它: + +* **数值积分**: 通过离散化和求和的方式,数值近似地计算了塔架的广义质量和广义刚度,这与[[Tower]]笔记中的积分公式相对应。 +* **考虑非线性效应**: 计算了重力去刚化刚度项和轴向缩短系数,这些是柔性体动力学中重要的非线性效应。 +* **模态调谐**: 实现了塔架模态刚度调谐功能,允许用户调整塔架的固有频率。 +* **计算派生参数**: 根据基本参数计算了塔架的固有频率和广义阻尼系数。 + +这些在`Coeff`中计算出的参数(存储在 `p` 结构体中)随后会被其他子程序(如`CalculatePositions`、`CalculateAngularPosVelPAcc`、`CalculateForcesMoments`和`FillAugmat`)使用,以构建和求解风力机的完整动力学方程。 +[Timestamp: 2026/01/12 16:28:08] \ No newline at end of file diff --git a/copilot-conversations/20260120_093252__[[meshmap]]分析SUBROUTINE_MeshMapCreate的实现方法and预弯.md b/copilot-conversations/20260120_093252__[[meshmap]]分析SUBROUTINE_MeshMapCreate的实现方法and预弯.md new file mode 100644 index 0000000..4514d5a --- /dev/null +++ b/copilot-conversations/20260120_093252__[[meshmap]]分析SUBROUTINE_MeshMapCreate的实现方法and预弯.md @@ -0,0 +1,554 @@ +--- +epoch: 1768872772586 +modelKey: gemini-2.5-flash|google +tags: + - copilot-conversation +--- + +**user**: [[meshmap]]分析SUBROUTINE MeshMapCreate的实现方法 +[Timestamp: 2026/01/20 09:32:52] + +**ai**: The `SUBROUTINE MeshMapCreate` is a core routine within the `meshmap` module, designed to establish the necessary data structures for mapping information between two distinct meshes: a source mesh (`Src`) and a destination mesh (`Dest`). This mapping facilitates the transfer of data such as motions, scalars, and loads between these meshes. + +Here's a detailed breakdown of its implementation: + +**1. Purpose** +The primary goal of `MeshMapCreate` is to: +* Determine the required sizes for mapping data structures. +* Allocate memory for these structures, specifically for motion/scalar mappings (`MeshMap%MapMotions`) and load mappings (`MeshMap%MapLoads`). +* Initialize these mappings by calling specialized subroutines based on the element types of the source and destination meshes. +* Allocate memory for `MeshMap%DisplacedPosition`. + +**2. Input and Output Parameters** +* `Src` (TYPE(MeshType), INTENT(IN)): The source mesh from which data will be mapped. +* `Dest` (TYPE(MeshType), INTENT(IN)): The destination mesh to which data will be mapped. +* `MeshMap` (TYPE(MeshMapType), INTENT(INOUT)): A data structure that will store all the mapping information. +* `ErrStat` (INTEGER(IntKi), INTENT(OUT)): An error status code indicating the success or failure of the operation. +* `ErrMsg` (CHARACTER(*), INTENT(OUT)): A descriptive error message if `ErrStat` indicates an error. + +**3. Initial Checks** +Before proceeding with any mapping, the subroutine performs a crucial check: +* It verifies that both the `Dest` and `Src` meshes are `Committed`. If either mesh is not committed (meaning its definition is not finalized), a fatal error is set, and the subroutine returns, as mapping cannot occur on incomplete mesh definitions. + +**4. Mapping for Motions and Scalars** +This section handles the creation of mappings for motion and scalar fields: +* **Condition**: The mapping is only attempted if both `Src` and `Dest` meshes possess motion fields (checked by `HasMotionFields(Src) .AND. HasMotionFields(Dest)`). +* **Allocation**: + * `PointsInMap` is determined by `Dest%Nnodes`, meaning the `MeshMap%MapMotions` array will have an entry for each node in the destination mesh. + * `MeshMap%MapMotions` is then allocated. If allocation fails, a fatal error is reported. +* **Initial Mapping Logic**: The subroutine uses a series of `IF` statements to select the appropriate mapping subroutine based on the element types of the destination and source meshes: + * **Destination has Line2 elements (`Dest%ElemTable(ELEMENT_LINE2)%nelem > 0`)**: + * If `Src` also has Line2 elements (`Src%ElemTable(ELEMENT_LINE2)%nelem > 0`), it calls `CreateMotionMap_L2_to_L2`. This subroutine, in turn, calls `CreateMapping_ProjectToLine2(Dest, Src, MeshMap%MapMotions, ELEMENT_LINE2, ...)`, which projects destination Line2 nodes onto source Line2 elements. + * If `Src` has Point elements (`Src%ElemTable(ELEMENT_POINT)%nelem > 0`), it calls `CreateMotionMap_P_to_L2`. This calls `CreateMapping_NearestNeighbor(Dest, Src, MeshMap%MapMotions, ELEMENT_LINE2, ELEMENT_POINT, ...)`, finding the nearest source point for each destination Line2 node. It also negates the `couple_arm` vector for consistency. + * **Destination has Point elements (`Dest%ElemTable(ELEMENT_POINT)%nelem > 0`)**: + * If `Src` also has Point elements (`Src%ElemTable(ELEMENT_POINT)%nelem > 0`), it calls `CreateMotionMap_P_to_P`. This calls `CreateMapping_NearestNeighbor(Dest, Src, MeshMap%MapMotions, ELEMENT_POINT, ELEMENT_POINT, ...)`, finding the nearest source point for each destination point. It also negates the `couple_arm` vector. + * If `Src` has Line2 elements (`Src%ElemTable(ELEMENT_LINE2)%nelem > 0`), it calls `CreateMotionMap_L2_to_P`. This calls `CreateMapping_ProjectToLine2(Dest, Src, MeshMap%MapMotions, ELEMENT_POINT, ...)`, projecting destination point nodes onto source Line2 elements. + +**5. Mapping for Loads** +This section handles the creation of mappings for load fields: +* **Condition**: The mapping is only attempted if both `Src` and `Dest` meshes possess load fields (checked by `HasLoadFields(Src) .AND. HasLoadFields(Dest)`). +* **Field Compatibility Checks**: It performs checks to ensure that the destination mesh can receive the loads from the source mesh. For example, if the source mesh has force fields, the destination mesh must have both force and moment fields. +* **Allocation**: + * `PointsInMap` is determined by `Src%Nnodes`, meaning the `MeshMap%MapLoads` array will have an entry for each node in the source mesh. + * `MeshMap%MapLoads` is then allocated. If allocation fails, a fatal error is reported. +* **Initial Mapping Logic**: Similar to motion mapping, it uses nested `IF` statements based on the element types of the destination and source meshes to call the appropriate `CreateLoadMap_` subroutines (e.g., `CreateLoadMap_L2_to_L2`, `CreateLoadMap_P_to_L2`, `CreateLoadMap_P_to_P`, `CreateLoadMap_L2_to_P`). While the implementations of these `CreateLoadMap_` subroutines are not provided in the context, they are expected to follow a similar logic to their `CreateMotionMap_` counterparts, potentially with adjusted roles for `Src` and `Dest` or specific considerations for load transfer. + +**6. Allocation of `DisplacedPosition`** +* After attempting to create motion and load mappings, the subroutine checks if `MeshMap%DisplacedPosition` has been allocated. +* If not, it allocates a 3D array for `MeshMap%DisplacedPosition`. The size is determined by `PointsInTmpMap` (the maximum of `Dest%Nnodes` and `Src%Nnodes` to accommodate either mapping type) and `ElementNodes` (which is 1 for point elements, 2 for Line2 elements). + +**7. Error Handling** +* The subroutine uses `ErrStat` and `ErrMsg` to communicate the status and any issues. +* `SetErrStat` is used to propagate errors from called subroutines or to set new errors within `MeshMapCreate`. +* Fatal errors (`ErrID_Fatal`) cause an immediate return. +* An informational message (`ErrID_Info`) is generated if a node is mapped to an element that is very close but not strictly "on" it (within a tolerance of 7.5mm), indicating a potential numerical precision issue. +* If neither `MapMotions` nor `MapLoads` is successfully allocated, a fatal error is issued, indicating incompatible fields for mapping. + +**Key Mapping Subroutines (Provided Implementations):** + +* **`CreateMapping_ProjectToLine2(Mesh1, Mesh2, NodeMap, Mesh1_TYPE, ErrStat, ErrMsg)`**: + * This routine projects nodes from `Mesh1` (e.g., destination nodes for motions) onto `Line2` elements of `Mesh2` (e.g., source Line2 elements). + * For each node in `Mesh1`, it iterates through all `Line2` elements in `Mesh2`. It calculates the projection of the `Mesh1` node's position onto the line segment defined by the `Line2` element. + * If the projection falls within the segment, it calculates the perpendicular distance. The `Line2` element with the minimum distance is chosen as the mapping target. + * `NodeMap(i)%OtherMesh_Element` stores the index of the mapped `Line2` element, and `NodeMap(i)%shape_fn` stores the linear interpolation weights (0.0 to 1.0) along the element. + * It includes logic to handle cases where a node is very close to the end of an element due to numerical precision. If a node cannot be mapped, a fatal error is reported, optionally with debug information. + +* **`CreateMapping_NearestNeighbor(Mesh1, Mesh2, NodeMap, Mesh1_TYPE, Mesh2_TYPE, ErrStat, ErrMsg)`**: + * This routine finds the nearest neighbor node in `Mesh2` (e.g., source nodes) for each node in `Mesh1` (e.g., destination nodes). + * It first identifies which nodes in `Mesh2` are relevant for the mapping based on `Mesh2_TYPE`. + * For each node in `Mesh1`, it iterates through the relevant nodes in `Mesh2`, calculating the Euclidean distance. + * The `Mesh2` node with the minimum distance is selected as the mapping target. + * `NodeMap(i)%OtherMesh_Element` stores the index of the nearest `Mesh2` node. + * `NodeMap(i)%distance` stores the minimum distance. + * `NodeMap(i)%couple_arm` stores the vector from the `Mesh1` node to the nearest `Mesh2` node. + +In essence, `MeshMapCreate` acts as an orchestrator, dynamically selecting and invoking specialized geometric mapping algorithms to prepare the `MeshMap` data structure for subsequent data transfer operations between potentially different mesh types. The initial comment by `bjj` suggests a potential future enhancement to allow for dynamic reallocation if nodes are added during a simulation, indicating the current focus is on initial setup. +[Timestamp: 2026/01/20 09:33:17] + +**user**: 中文回复 +[Timestamp: 2026/01/20 09:33:23] + +**ai**: `SUBROUTINE MeshMapCreate` 是 `meshmap` 模块中的一个核心子程序,旨在为两个不同的网格(源网格 `Src` 和目标网格 `Dest`)之间的数据映射建立必要的数据结构。这种映射有助于在这些网格之间传输运动、标量和载荷等数据。 + +以下是其实现的详细分析: + +**1. 目的** +`MeshMapCreate` 的主要目标是: +* 确定映射数据结构所需的尺寸。 +* 为这些结构分配内存,特别是用于运动/标量映射 (`MeshMap%MapMotions`) 和载荷映射 (`MeshMap%MapLoads`)。 +* 根据源网格和目标网格的元素类型,通过调用专门的子程序来初始化这些映射。 +* 为 `MeshMap%DisplacedPosition` 分配内存。 + +**2. 输入和输出参数** +* `Src` (TYPE(MeshType), INTENT(IN)):数据将从中映射的源网格。 +* `Dest` (TYPE(MeshType), INTENT(IN)):数据将映射到的目标网格。 +* `MeshMap` (TYPE(MeshMapType), INTENT(INOUT)):一个将存储所有映射信息的数据结构。 +* `ErrStat` (INTEGER(IntKi), INTENT(OUT)):指示操作成功或失败的错误状态码。 +* `ErrMsg` (CHARACTER(*), INTENT(OUT)):如果 `ErrStat` 指示错误,则为描述性错误消息。 + +**3. 初始检查** +在进行任何映射之前,子程序会执行一个关键检查: +* 它验证 `Dest` 和 `Src` 网格是否都已 `Committed`(即其定义已最终确定)。如果任一网格未提交,则会设置一个致命错误并返回子程序,因为无法对不完整的网格定义进行映射。 + +**4. 运动和标量映射** +此部分处理运动和标量场的映射创建: +* **条件**:仅当 `Src` 和 `Dest` 网格都具有运动场时才尝试映射(通过 `HasMotionFields(Src) .AND. HasMotionFields(Dest)` 检查)。 +* **分配**: + * `PointsInMap` 由 `Dest%Nnodes` 确定,这意味着 `MeshMap%MapMotions` 数组将为目标网格中的每个节点分配一个条目。 + * 然后分配 `MeshMap%MapMotions`。如果分配失败,则报告致命错误。 +* **初始映射逻辑**:子程序使用一系列 `IF` 语句根据目标网格和源网格的元素类型选择适当的映射子程序: + * **目标网格具有 Line2 元素 (`Dest%ElemTable(ELEMENT_LINE2)%nelem > 0`)**: + * 如果 `Src` 也具有 Line2 元素 (`Src%ElemTable(ELEMENT_LINE2)%nelem > 0`),则调用 `CreateMotionMap_L2_to_L2`。此子程序又会调用 `CreateMapping_ProjectToLine2(Dest, Src, MeshMap%MapMotions, ELEMENT_LINE2, ...)`,将目标 Line2 节点投影到源 Line2 元素上。 + * 如果 `Src` 具有 Point 元素 (`Src%ElemTable(ELEMENT_POINT)%nelem > 0`),则调用 `CreateMotionMap_P_to_L2`。此子程序调用 `CreateMapping_NearestNeighbor(Dest, Src, MeshMap%MapMotions, ELEMENT_LINE2, ELEMENT_POINT, ...)`,为每个目标 Line2 节点找到最近的源点。它还会为了保持一致性而对 `couple_arm` 向量取反。 + * **目标网格具有 Point 元素 (`Dest%ElemTable(ELEMENT_POINT)%nelem > 0`)**: + * 如果 `Src` 也具有 Point 元素 (`Src%ElemTable(ELEMENT_POINT)%nelem > 0`),则调用 `CreateMotionMap_P_to_P`。此子程序调用 `CreateMapping_NearestNeighbor(Dest, Src, MeshMap%MapMotions, ELEMENT_POINT, ELEMENT_POINT, ...)`,为每个目标点找到最近的源点。它还会对 `couple_arm` 向量取反。 + * 如果 `Src` 具有 Line2 元素 (`Src%ElemTable(ELEMENT_LINE2)%nelem > 0`),则调用 `CreateMotionMap_L2_to_P`。此子程序调用 `CreateMapping_ProjectToLine2(Dest, Src, MeshMap%MapMotions, ELEMENT_POINT, ...)`,将目标点节点投影到源 Line2 元素上。 + +**5. 载荷映射** +此部分处理载荷场的映射创建: +* **条件**:仅当 `Src` 和 `Dest` 网格都具有载荷场时才尝试映射(通过 `HasLoadFields(Src) .AND. HasLoadFields(Dest)` 检查)。 +* **字段兼容性检查**:它执行检查以确保目标网格可以接收来自源网格的载荷。例如,如果源网格具有力场,则目标网格必须同时具有力场和力矩场。 +* **分配**: + * `PointsInMap` 由 `Src%Nnodes` 确定,这意味着 `MeshMap%MapLoads` 数组将为源网格中的每个节点分配一个条目。 + * 然后分配 `MeshMap%MapLoads`。如果分配失败,则报告致命错误。 +* **初始映射逻辑**:与运动映射类似,它根据目标网格和源网格的元素类型使用嵌套的 `IF` 语句来调用适当的 `CreateLoadMap_` 子程序(例如,`CreateLoadMap_L2_to_L2`、`CreateLoadMap_P_to_L2`、`CreateLoadMap_P_to_P`、`CreateLoadMap_L2_to_P`)。虽然这些 `CreateLoadMap_` 子程序的实现未在上下文中提供,但它们预计会遵循与其 `CreateMotionMap_` 对应子程序类似的逻辑,可能对 `Src` 和 `Dest` 的角色进行调整或对载荷传输进行特定考虑。 + +**6. `DisplacedPosition` 的分配** +* 在尝试创建运动和载荷映射之后,子程序检查 `MeshMap%DisplacedPosition` 是否已分配。 +* 如果未分配,它会为 `MeshMap%DisplacedPosition` 分配一个 3D 数组。大小由 `PointsInTmpMap`(为适应任一映射类型,取 `Dest%Nnodes` 和 `Src%Nnodes` 的最大值)和 `ElementNodes`(点元素为 1,Line2 元素为 2)确定。 + +**7. 错误处理** +* 子程序使用 `ErrStat` 和 `ErrMsg` 来传达状态和任何问题。 +* `SetErrStat` 用于传播来自被调用子程序的错误或在 `MeshMapCreate` 中设置新错误。 +* 致命错误 (`ErrID_Fatal`) 会导致立即返回。 +* 如果节点映射到非常接近但并非严格“在”其上的元素(在 7.5 毫米的容差范围内),则会生成一条信息性消息 (`ErrID_Info`),表明可能存在数值精度问题。 +* 如果 `MapMotions` 和 `MapLoads` 都未能成功分配,则会发出致命错误,表明映射的字段不兼容。 + +**关键映射子程序(已提供的实现):** + +* **`CreateMapping_ProjectToLine2(Mesh1, Mesh2, NodeMap, Mesh1_TYPE, ErrStat, ErrMsg)`**: + * 此例程将 `Mesh1` 中的节点(例如,运动的目标节点)投影到 `Mesh2` 中的 `Line2` 元素(例如,源 Line2 元素)上。 + * 对于 `Mesh1` 中的每个节点,它会遍历 `Mesh2` 中的所有 `Line2` 元素。它计算 `Mesh1` 节点位置到由 `Line2` 元素定义的线段的投影。 + * 如果投影落在该线段内,则计算垂直距离。选择距离最小的 `Line2` 元素作为映射目标。 + * `NodeMap(i)%OtherMesh_Element` 存储映射的 `Line2` 元素的索引,`NodeMap(i)%shape_fn` 存储沿元素的线性插值权重(0.0 到 1.0)。 + * 它包含处理由于数值精度问题导致节点非常接近元素末端的情况的逻辑。如果节点无法映射,则报告致命错误,并可选择提供调试信息。 + +* **`CreateMapping_NearestNeighbor(Mesh1, Mesh2, NodeMap, Mesh1_TYPE, Mesh2_TYPE, ErrStat, ErrMsg)`**: + * 此例程为 `Mesh1` 中的每个节点(例如,目标节点)找到 `Mesh2` 中(例如,源节点)最近的邻居节点。 + * 它首先根据 `Mesh2_TYPE` 识别 `Mesh2` 中与映射相关的节点。 + * 对于 `Mesh1` 中的每个节点,它会遍历 `Mesh2` 中的相关节点,计算欧几里得距离。 + * 选择距离最小的 `Mesh2` 节点作为映射目标。 + * `NodeMap(i)%OtherMesh_Element` 存储最近的 `Mesh2` 节点的索引。 + * `NodeMap(i)%distance` 存储最小距离。 + * `NodeMap(i)%couple_arm` 存储从 `Mesh1` 节点到最近 `Mesh2` 节点的向量。 + +本质上,`MeshMapCreate` 充当协调器,动态选择和调用专门的几何映射算法,以准备 `MeshMap` 数据结构,用于在可能不同的网格类型之间进行后续数据传输操作。`bjj` 的初始注释表明未来可能会增强功能,以允许在模拟期间添加节点时进行动态重新分配,这表明当前重点是初始设置。 +[Timestamp: 2026/01/20 09:33:36] + +**user**: 我现在有两套l2mesh,完整解释两套网格的载荷、运动映射方法 +[Timestamp: 2026/01/20 09:46:09] + +**ai**: 好的,假设您有两套 Line2 类型的网格,我们称之为源网格 `Src` 和目标网格 `Dest`。我们将详细解释 `SUBROUTINE MeshMapCreate` 如何处理这两种网格之间的载荷和运动映射。 + +在 `MeshMapCreate` 子程序中,当 `Src` 和 `Dest` 都是 Line2 网格时,会触发特定的映射逻辑。 + +### 1. 运动和标量映射 (Motion and Scalar Mapping) + +当 `Src` 和 `Dest` 都具有运动场 (`HasMotionFields(Src) .AND. HasMotionFields(Dest)`) 并且它们都是 Line2 元素网格时,`MeshMapCreate` 会执行以下步骤: + +1. **确定映射大小**: + * `PointsInMap` 将被设置为 `Dest%Nnodes`(目标网格的节点数)。这意味着 `MeshMap%MapMotions` 数组将为目标网格中的每个节点分配一个条目。 + * `ElementNodes` 将设置为 2,因为 Line2 元素有两个节点。 + +2. **分配 `MeshMap%MapMotions`**: + * 子程序会尝试分配 `MeshMap%MapMotions(PointsInMap)`。如果分配失败,将报告致命错误。 + +3. **调用 `CreateMotionMap_L2_to_L2`**: + * 由于 `Dest%ElemTable(ELEMENT_LINE2)%nelem > 0` (目标网格有 Line2 元素) 且 `Src%ElemTable(ELEMENT_LINE2)%nelem > 0` (源网格也有 Line2 元素),`MeshMapCreate` 会调用 `CreateMotionMap_L2_to_L2` 子程序。 + +4. **`CreateMotionMap_L2_to_L2` 的实现**: + * 这个子程序的主要任务是调用 `CreateMapping_ProjectToLine2`。 + * 调用方式为:`CALL CreateMapping_ProjectToLine2(Dest, Src, MeshMap%MapMotions, ELEMENT_LINE2, ErrStat2, ErrMsg2)`。 + * 这里,`Mesh1` 参数是 `Dest` 网格,`Mesh2` 参数是 `Src` 网格。 + * `NodeMap` 是 `MeshMap%MapMotions`。 + * `Mesh1_TYPE` 是 `ELEMENT_LINE2`。 + * `Mesh2_TYPE` 在 `CreateMapping_ProjectToLine2` 中被硬编码为 `ELEMENT_LINE2`。 + +5. **`CreateMapping_ProjectToLine2` 的实现 (L2-to-L2 运动映射)**: + * 这个子程序的目标是将 `Mesh1` (即 `Dest` 网格) 的每个节点投影到 `Mesh2` (即 `Src` 网格) 的 Line2 元素上,以找到最佳的映射关系。 + * **初始化**: `NodeMap` 中的每个条目 `NodeMap(i)%OtherMesh_Element` 被初始化为 `NODE_NOT_MAPPED`,表示尚未映射。 + * **遍历目标网格节点**: + * 它会遍历 `Mesh1` (目标网格 `Dest`) 中所有 `ELEMENT_LINE2` 类型的元素 (`iElem`)。 + * 对于每个元素,它会遍历该元素的所有节点 (`iNode`)。 + * 获取当前目标节点 `i` 的三维坐标 `Mesh1_xyz = Mesh1%Position(:, i)`。 + * **寻找最近的源 Line2 元素**: + * 对于每个目标节点 `i`,它会遍历 `Mesh2` (源网格 `Src`) 中所有 `ELEMENT_LINE2` 类型的元素 (`jElem`)。 + * 对于每个源 Line2 元素 `jElem`,它会获取其两个节点 `n1` 和 `n2` 的坐标。 + * **投影计算**: + * 计算从 `n1` 到 `n2` 的向量 `n1_n2_vector`。 + * 计算从 `n1` 到目标节点 `i` 的向量 `n1_Point_vector`。 + * 通过点积计算目标节点 `i` 在 `n1_n2_vector` 方向上的投影位置 `elem_position`。 + * `elem_position = DOT_PRODUCT(n1_n2_vector, n1_Point_vector) / DOT_PRODUCT(n1_n2_vector, n1_n2_vector)`。 + * **判断是否在元素上**: + * 如果 `elem_position` 在 `[0.0, 1.0]` 之间(包括边界上的数值容差),则认为目标节点投影到了源 Line2 元素上。 + * 如果不在元素上,但非常接近元素端点(例如,小于 7.5 毫米),则会记录为“最近的元素”,并可能在后续作为映射目标。 + * **计算距离并选择最佳映射**: + * 如果目标节点投影在源 Line2 元素上,则计算目标节点到该 Line2 元素的垂直距离(实际上是距离的平方)。 + * 如果当前 Line2 元素的距离小于之前找到的最小距离 `min_dist`,则更新 `min_dist`,并将当前源 Line2 元素 `jElem` 及其投影位置 `elem_position` 记录为最佳映射。 + * `NodeMap(i)%OtherMesh_Element` 存储源 Line2 元素的索引 `jElem`。 + * `NodeMap(i)%shape_fn(1)` 和 `NodeMap(i)%shape_fn(2)` 存储插值形函数值,分别为 `1.0 - elem_position` 和 `elem_position`。这些形函数用于在源 Line2 元素上进行线性插值,以获取目标节点处的运动值。 + * **错误处理**: 如果一个目标节点无法投影到任何源 Line2 元素上(即使考虑了数值容差),则会报告致命错误。 + +**总结 L2-to-L2 运动映射**: 对于目标网格 `Dest` 中的每个节点,系统会找到源网格 `Src` 中离它最近的 Line2 元素,并将目标节点映射到该源 Line2 元素上的一个投影点。映射信息包括源元素的索引和在该元素上的插值权重。 + +### 2. 载荷映射 (Load Mapping) + +当 `Src` 和 `Dest` 都具有载荷场 (`HasLoadFields(Src) .AND. HasLoadFields(Dest)`) 并且它们都是 Line2 元素网格时,`MeshMapCreate` 会执行以下步骤: + +1. **兼容性检查**: + * 子程序会检查载荷场的兼容性。例如,如果源网格有力 (`Src%FieldMask(MASKID_Force)`),则目标网格必须有力 (`Dest%FieldMask(MASKID_Force)`) 和力矩 (`Dest%FieldMask(MASKID_Moment)`)。如果源网格有力矩 (`Src%FieldMask(MASKID_Moment)`),则目标网格必须有力矩。这些是确保载荷可以正确传输的必要条件。 + +2. **确定映射大小**: + * `PointsInMap` 将被设置为 `Src%Nnodes`(源网格的节点数)。这意味着 `MeshMap%MapLoads` 数组将为源网格中的每个节点分配一个条目。 + * `ElementNodes` 将设置为 2,因为 Line2 元素有两个节点。 + +3. **分配 `MeshMap%MapLoads`**: + * 子程序会尝试分配 `MeshMap%MapLoads(PointsInMap)`。如果分配失败,将报告致命错误。 + +4. **调用 `CreateLoadMap_L2_to_L2`**: + * 由于 `Dest%ElemTable(ELEMENT_LINE2)%nelem > 0` (目标网格有 Line2 元素) 且 `Src%ElemTable(ELEMENT_LINE2)%nelem > 0` (源网格也有 Line2 元素),`MeshMapCreate` 会调用 `CreateLoadMap_L2_to_L2` 子程序。 + +5. **`CreateLoadMap_L2_to_L2` 的实现 (未在提供的代码中,但可推断)**: + * 根据 `CreateMotionMap_L2_to_L2` 的模式,`CreateLoadMap_L2_to_L2` 也很可能会调用 `CreateMapping_ProjectToLine2`。 + * 然而,对于载荷映射,源和目标网格的角色通常是相反的。载荷是从源网格传递到目标网格。因此,在载荷映射中,我们通常需要将**源网格的节点**映射到**目标网格的元素**上。 + * 因此,推断的调用方式可能是:`CALL CreateMapping_ProjectToLine2(Src, Dest, MeshMap%MapLoads, ELEMENT_LINE2, ErrStat2, ErrMsg2)`。 + * 这里,`Mesh1` 参数是 `Src` 网格,`Mesh2` 参数是 `Dest` 网格。 + * `NodeMap` 是 `MeshMap%MapLoads`。 + * `Mesh1_TYPE` 是 `ELEMENT_LINE2`。 + * `Mesh2_TYPE` 在 `CreateMapping_ProjectToLine2` 中被硬编码为 `ELEMENT_LINE2`。 + +6. **`CreateMapping_ProjectToLine2` 的实现 (L2-to-L2 载荷映射)**: + * 与运动映射类似,但角色互换。它将 `Mesh1` (即 `Src` 网格) 的每个节点投影到 `Mesh2` (即 `Dest` 网格) 的 Line2 元素上。 + * **遍历源网格节点**: + * 它会遍历 `Mesh1` (源网格 `Src`) 中所有 `ELEMENT_LINE2` 类型的元素 (`iElem`)。 + * 对于每个元素,它会遍历该元素的所有节点 (`iNode`)。 + * 获取当前源节点 `i` 的三维坐标 `Mesh1_xyz = Mesh1%Position(:, i)`。 + * **寻找最近的目标 Line2 元素**: + * 对于每个源节点 `i`,它会遍历 `Mesh2` (目标网格 `Dest`) 中所有 `ELEMENT_LINE2` 类型的元素 (`jElem`)。 + * 执行与运动映射中相同的投影计算和距离判断逻辑。 + * `NodeMap(i)%OtherMesh_Element` 存储目标 Line2 元素的索引 `jElem`。 + * `NodeMap(i)%shape_fn(1)` 和 `NodeMap(i)%shape_fn(2)` 存储插值形函数值,用于在目标 Line2 元素上进行线性插值,以确定源节点处的载荷如何分布到目标元素上。 + * **错误处理**: 同样,如果一个源节点无法投影到任何目标 Line2 元素上,则会报告致命错误。 + +**总结 L2-to-L2 载荷映射**: 对于源网格 `Src` 中的每个节点,系统会找到目标网格 `Dest` 中离它最近的 Line2 元素,并将源节点映射到该目标 Line2 元素上的一个投影点。映射信息包括目标元素的索引和在该元素上的插值权重。这些权重将用于将源节点上的载荷(力、力矩)分配到目标 Line2 元素的两个节点上。 + +### 3. `DisplacedPosition` 的分配 + +无论载荷或运动映射是否发生,如果 `MeshMap%DisplacedPosition` 尚未分配,它都会被分配。 +* `PointsInTmpMap` 在 Line2-to-Line2 情况下,对于运动映射是 `Dest%Nnodes`,对于载荷映射是 `Src%Nnodes`。因此,`PointsInTmpMap` 将取两者中的最大值。 +* `ElementNodes` 在 Line2 网格情况下为 2。 +* `MeshMap%DisplacedPosition` 将被分配为一个 `3 x PointsInTmpMap x ElementNodes` 的数组,用于存储位移后的位置信息。 + +### 总结 + +当您有两套 Line2 网格进行映射时: + +* **运动映射 (L2-to-L2)**:目标网格 `Dest` 中的每个节点会被投影到源网格 `Src` 中最近的 Line2 元素上。映射结果存储在 `MeshMap%MapMotions` 中,包含源元素的索引和插值形函数,用于从源网格插值运动到目标网格节点。 +* **载荷映射 (L2-to-L2)**:源网格 `Src` 中的每个节点会被投影到目标网格 `Dest` 中最近的 Line2 元素上。映射结果存储在 `MeshMap%MapLoads` 中,包含目标元素的索引和插值形函数,用于将源网格节点上的载荷分配到目标网格元素节点。 + +这两种映射都依赖于 `CreateMapping_ProjectToLine2` 子程序,该子程序通过几何投影和距离计算来确定节点与 Line2 元素之间的对应关系。关键的区别在于 `CreateMapping_ProjectToLine2` 被调用的参数,特别是 `Mesh1` 和 `Mesh2` 的角色,这决定了是“目标节点找源元素”还是“源节点找目标元素”。 +[Timestamp: 2026/01/20 09:46:27] + +**user**: [[meshmap]][[CalculatePositions]]我现在的两套网格,aero部分是有风电叶片预弯的网格,elast部分叶片网格是直的,两套网格是否可以匹配 +[Timestamp: 2026/01/20 10:11:20] + +**ai**: 您提出的问题是关于两套网格的匹配性:一套是气动(aero)部分使用的**预弯叶片网格**,另一套是弹性(elast)部分使用的**直叶片网格**。在 `[[meshmap]]` 和 `[[CalculatePositions]]` 的上下文中,这两套网格是否可以匹配,以及如何匹配。 + +**核心观点:** + +从 `MeshMapCreate` 的实现来看,它主要依赖于网格节点的**几何位置**来建立映射关系。因此,如果两套网格的节点在**初始(未变形)状态下**的几何位置差异很大,那么直接进行映射可能会导致不准确或失败。 + +然而,OpenFAST(以及类似的耦合仿真工具)通常会处理这种几何差异,通过在仿真过程中**动态更新网格位置**来实现匹配。 + +### `MeshMapCreate` 的作用和限制 + +`MeshMapCreate` 子程序负责在仿真开始时建立**初始的**网格映射关系。它会: + +1. **检查网格是否已提交**: 确保网格定义完整。 +2. **分配映射数据结构**: 为运动和载荷分配 `MeshMap%MapMotions` 和 `MeshMap%MapLoads`。 +3. **调用映射算法**: 根据网格类型(例如,Line2-to-Line2)调用 `CreateMapping_ProjectToLine2` 或 `CreateMapping_NearestNeighbor`。 + +这些映射算法的核心是: + +* **`CreateMapping_ProjectToLine2`**: 将一个网格的节点**投影**到另一个网格的 Line2 元素上,找到最近的投影点和插值权重。 +* **`CreateMapping_NearestNeighbor`**: 找到一个网格的节点在另一个网格中的**最近邻**节点。 + +**对于您的情况:** + +* **Aero 网格 (预弯叶片)**:这代表了叶片的**初始几何形状**,包含了预弯信息。 +* **Elast 网格 (直叶片)**:这代表了叶片的**未变形参考构型**,通常是直的。 + +如果 `MeshMapCreate` 直接尝试将预弯网格的节点映射到直网格的节点或元素上,由于几何形状的显著差异(预弯与直),**初始映射的准确性会很差,甚至可能失败**。`CreateMapping_ProjectToLine2` 会寻找最近的投影点,但如果叶片形状差异太大,投影可能落在元素之外,或者找到的“最近”元素在物理上并不对应。 + +### `CalculatePositions` 的作用和动态匹配 + +`[[CalculatePositions]]` 子程序在 OpenFAST 的弹性动力学 (Elastodynamics) 模块中扮演着关键角色。它的主要功能是: + +* **计算各个点的瞬时位置**: 根据系统的连续状态 `x`(包括位移和旋转)和参数 `p`,计算风力机各个部件(包括塔架和叶片)在**当前时刻**的瞬时位置。 +* **考虑变形**: 特别是对于叶片,`CalculatePositions` 会根据弹性变形状态 (`x%QT(DOF_BF(K,1))` 等) 计算叶片节点的实际位置 `RtHSdat%rS`。这意味着,即使弹性部分的**参考网格**是直的,在仿真过程中,`CalculatePositions` 会根据叶片的变形(包括预弯和柔性变形)计算出其**实际的、变形后的位置**。 + +**因此,匹配的关键在于:** + +1. **初始几何差异**: `MeshMapCreate` 在建立初始映射时,会使用网格的**初始几何位置**。如果 aero 网格是预弯的,而 elast 网格是直的,那么在**初始时刻**,这两套网格的几何形状是不同的。 +2. **动态变形**: 在仿真过程中,弹性部分的直叶片网格会根据其变形状态(包括预弯效应,如果预弯被建模为一种初始变形)计算出其**实际的、变形后的位置**。 +3. **映射的更新**: 理想情况下,映射关系应该在每个时间步或在变形显著时进行更新,以反映网格的实际几何形状。`MeshMapCreate` 的注释 `bjj: maybe the MeshMapCreate routine shouldn't actually allocate arrays; allocate them in the "IF (RemapFlag)" sections so that if people add nodes during the simulation, the structures get reallocated to correct size?` 也暗示了这种动态更新的需求。 + +### 结论和建议 + +**两套网格是否可以匹配?** + +* **直接匹配(基于初始几何)**: 如果 aero 网格是预弯的,而 elast 网格是直的,并且 `MeshMapCreate` 仅基于它们的**初始几何位置**进行映射,那么**匹配会非常困难,甚至可能失败**。`CreateMapping_ProjectToLine2` 可能会因为几何差异过大而找不到合适的投影点,或者找到的映射关系不准确。 +* **通过动态变形匹配**: 在 OpenFAST 这样的耦合仿真中,通常会通过以下方式处理: + 1. **弹性网格的参考构型**: 弹性部分的直叶片网格是其**未变形的参考构型**。 + 2. **预弯的建模**: 预弯通常被建模为弹性叶片在**初始状态下的一个变形**,或者在坐标系定义中考虑。`CalculatePositions` 会将这种预弯效应(以及其他柔性变形)计算到叶片的实际位置中。 + 3. **气动网格的变形**: 气动网格(预弯叶片)在仿真过程中也会根据弹性部分的变形进行更新,使其与弹性叶片的**实际变形形状**保持一致。 + 4. **映射的动态更新**: 关键在于,在每个时间步,当弹性叶片发生变形时,气动网格的**实际位置**会根据弹性叶片的变形进行更新。然后,映射算法(或其后续的数据传输逻辑)会使用这些**更新后的、变形后的位置**来传递载荷和运动。 + +**为了实现准确的匹配,通常需要确保:** + +1. **几何一致性**: 在进行映射时,两套网格的**实际几何形状**应该尽可能接近。这意味着,如果 aero 网格是预弯的,那么在进行映射时,elast 网格也应该被“变形”到预弯状态,或者 aero 网格的节点位置是基于 elast 网格的变形来计算的。 +2. **坐标系和参考点**: 确保两套网格的坐标系定义和参考点是一致的,或者有明确的转换关系。 +3. **映射算法的鲁棒性**: `CreateMapping_ProjectToLine2` 包含了一个 7.5 毫米的容差,用于处理节点非常接近元素端点的情况。这在一定程度上增加了鲁棒性,但如果初始几何差异过大,这个容差可能不足以解决问题。 + +**具体建议:** + +* **检查 OpenFAST 的具体实现**: 了解 OpenFAST 如何处理预弯叶片的气动-弹性耦合。通常,气动网格的节点位置会根据弹性叶片的变形(包括预弯)进行更新。这意味着,在进行映射时,气动网格的节点位置实际上是**变形后的位置**。 +* **确保 `Src` 和 `Dest` 在映射时具有相似的几何**: + * 如果 `Src` 是 aero 网格(预弯),`Dest` 是 elast 网格(直),那么在调用 `MeshMapCreate` 之前,可能需要将 `Dest` 网格的节点位置**预先变形**到与 `Src` 相似的预弯状态,或者 `Src` 网格的初始位置是基于 `Dest` 网格的参考构型加上预弯变形来定义的。 + * 更常见的情况是,在每个时间步,弹性模块会计算出叶片的**实际变形位置**(包括预弯),然后气动模块会使用这些位置来构建其气动网格。映射发生在这些**瞬时变形位置**之间。 +* **关注错误信息**: 如果 `MeshMapCreate` 报告致命错误,例如“Node ... does not project onto any line2 element”,这通常意味着几何差异过大,导致映射失败。 + +总之,虽然 `MeshMapCreate` 依赖于几何位置,但 OpenFAST 的整体框架会通过 `CalculatePositions` 等子程序在仿真过程中动态处理叶片的变形。因此,关键在于确保在进行网格映射时,所使用的网格位置(无论是源网格还是目标网格)能够准确反映叶片的**实际几何形状**,包括预弯效应。如果初始几何差异过大,直接的静态映射会存在问题,需要通过动态更新网格位置来解决。 +[Timestamp: 2026/01/20 10:11:36] + +**user**: [[CalculatePositions]][[CalculateAngularPosVelPAcc]]如果我在结构上使用预弯的叶片模型和网格,如何使用模态计算叶片变形量 +[Timestamp: 2026/01/21 14:35:09] + +**ai**: 您的问题是关于在结构上使用预弯叶片模型和网格时,如何使用模态计算叶片变形量,结合 `[[CalculatePositions]]` 和 `[[CalculateAngularPosVelPAcc]]` 子程序。 + +在 OpenFAST 这样的多体动力学仿真工具中,叶片的变形通常通过**模态叠加法**来表示。这意味着叶片的总变形是其各个振动模态乘以相应的模态坐标(或广义坐标)的线性组合。 + +### 1. 预弯叶片模型和网格的结构表示 + +当您说“结构上使用预弯的叶片模型和网格”时,这通常意味着: + +* **初始几何**: 您的叶片网格在**未变形状态下**就已经包含了预弯的几何形状。这与之前讨论的“直叶片网格”作为参考构型不同。在这种情况下,叶片的“零变形”位置已经是预弯的。 +* **模态形状**: 弹性模态(如挥舞、摆振、扭转模态)是基于这个**预弯几何**来计算的。模态形状函数 `p%TwistedSF` 和 `p%AxRedBld` 包含了叶片沿展向的几何和结构特性,它们会反映预弯的影响。 + +### 2. `CalculatePositions` 如何计算叶片变形量 + +`CalculatePositions` 子程序的核心任务是计算风力机各个部件在**当前时刻**的瞬时位置。对于叶片,它通过模态叠加来计算其变形。 + +我们来看 `CalculatePositions` 中计算叶片节点位置的关键部分: + +```fortran + DO K = 1,p%NumBl ! Loop through all blades + ... + DO J = 1,p%BldNodes ! Loop through the blade nodes / elements + + ! Calculate the position vector of the current node: + + RtHSdat%rS0S(:,K,J) = ( p%TwistedSF(K,1,1,J,0)*x%QT( DOF_BF(K,1) ) & ! 展向位移分量 (j1方向) + + p%TwistedSF(K,1,2,J,0)*x%QT( DOF_BF(K,2) ) & + + p%TwistedSF(K,1,3,J,0)*x%QT( DOF_BE(K,1) ) )*CoordSys%j1(K,:) & + + ( p%TwistedSF(K,2,1,J,0)*x%QT( DOF_BF(K,1) ) & ! 弦向位移分量 (j2方向) + + p%TwistedSF(K,2,2,J,0)*x%QT( DOF_BF(K,2) ) & + + p%TwistedSF(K,2,3,J,0)*x%QT( DOF_BE(K,1) ) )*CoordSys%j2(K,:) & + + ( p%RNodes(J) - 0.5* & ! 展向位置分量 (j3方向) + ( p%AxRedBld(K,1,1,J)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BF(K,1) ) & + + p%AxRedBld(K,2,2,J)*x%QT( DOF_BF(K,2) )*x%QT( DOF_BF(K,2) ) & + + p%AxRedBld(K,3,3,J)*x%QT( DOF_BE(K,1) )*x%QT( DOF_BE(K,1) ) & + + 2.0*p%AxRedBld(K,1,2,J)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BF(K,2) ) & + + 2.0*p%AxRedBld(K,2,3,J)*x%QT( DOF_BF(K,2) )*x%QT( DOF_BE(K,1) ) & + + 2.0*p%AxRedBld(K,1,3,J)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BE(K,1) ) ) )*CoordSys%j3(K,:) + RtHSdat%rQS (:,K,J) = RtHSdat%rS0S(:,K,J) + p%HubRad*CoordSys%j3(K,:) + RtHSdat%rS (:,K,J) = RtHSdat%rQS (:,K,J) + RtHSdat%rQ + END DO + END DO +``` + +**解释:** + +1. **`x%QT(...)`**: `x` 是连续状态变量,`x%QT` 包含了广义坐标(模态坐标)。 + * `DOF_BF(K,1)` 和 `DOF_BF(K,2)` 通常代表叶片 `K` 的第一和第二阶**挥舞 (Flapwise)** 模态的模态坐标。 + * `DOF_BE(K,1)` 通常代表叶片 `K` 的第一阶**摆振 (Edgewise)** 模态的模态坐标。 + * (注意:这里没有直接看到扭转模态的广义坐标,但通常也会有类似的表示,可能在 `DOF_BE` 中或通过其他方式处理。) +2. **`p%TwistedSF(K,dim,mode,J,0)`**: 这是**模态形状函数 (Mode Shape Function)**。 + * `K`: 叶片编号。 + * `dim`: 位移分量方向(1代表 `j1` 方向,2代表 `j2` 方向)。 + * `mode`: 模态索引(例如,1代表第一阶挥舞,2代表第二阶挥舞,3代表第一阶摆振)。 + * `J`: 叶片沿展向的节点索引。 + * `0`: 表示位移形状函数(而不是旋转形状函数)。 + * 这些形状函数描述了在给定模态下,叶片沿展向不同位置的**单位变形量**。它们是预先通过有限元分析(FEA)等方法计算得到的,并且**已经包含了叶片的初始预弯几何**。 +3. **`CoordSys%j1(K,:)`, `CoordSys%j2(K,:)`, `CoordSys%j3(K,:)`**: 这些是叶片 `K` 局部坐标系的单位向量。`j3` 通常沿叶片展向,`j1` 和 `j2` 垂直于 `j3`,分别代表挥舞和摆振方向。 +4. **`p%RNodes(J)`**: 这是叶片节点 `J` 沿展向的**未变形径向位置**。 +5. **`p%AxRedBld(...)`**: 这些项是**轴向缩短 (Axial Shortening)** 效应的系数,表示由于大变形引起的展向长度缩短。它们是模态坐标的二次项,用于修正叶片沿展向的实际位置。 + +**如何使用模态计算叶片变形量:** + +叶片上任意一点 `J` 的**变形位移**可以表示为: + +$ \vec{u}_J = \sum_{m} q_m \vec{\phi}_{m,J} $ + +其中: +* $ \vec{u}_J $ 是节点 `J` 的变形位移向量。 +* $ q_m $ 是第 $m$ 阶模态的模态坐标(即 `x%QT(DOF_BF(K,1))` 等)。 +* $ \vec{\phi}_{m,J} $ 是第 $m$ 阶模态在节点 `J` 处的模态形状向量。 + +在 `CalculatePositions` 中,`RtHSdat%rS0S(:,K,J)` 实际上计算的是从叶片根部 (S(0)) 到当前节点 (S(RNodes(J))) 的**相对位置向量**。这个向量包含了: + +* **未变形的展向位置**: `p%RNodes(J)` 沿 `CoordSys%j3(K,:)` 方向。 +* **模态引起的变形位移**: + * `j1` 方向的变形:`p%TwistedSF(K,1,mode,J,0) * x%QT(DOF_BF/BE)` + * `j2` 方向的变形:`p%TwistedSF(K,2,mode,J,0) * x%QT(DOF_BF/BE)` +* **轴向缩短效应**: `0.5 * (p%AxRedBld(...) * x%QT(...) * x%QT(...))` 沿 `CoordSys%j3(K,:)` 方向。 + +因此,**叶片变形量**就是当前计算出的位置与叶片在**初始预弯状态下**的未变形位置之间的差异。由于 `p%TwistedSF` 已经包含了预弯几何,所以 `x%QT` 乘以 `p%TwistedSF` 得到的位移就是**相对于预弯构型的柔性变形**。 + +### 3. `CalculateAngularPosVelPAcc` 的作用 + +`CalculateAngularPosVelPAcc` 子程序计算各个部件的**角位置、角速度和角加速度**。对于叶片,它也使用模态叠加来计算其**弹性旋转**。 + +关键部分如下: + +```fortran + DO K = 1,p%NumBl ! Loop through all blades + DO J = 0,p%TipNode ! Loop through the blade nodes / elements + ... + 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,:) + 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%AngPosHM(:,K,J ) = x%QT (DOF_BF(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,1),0,:) & + + x%QT (DOF_BF(K,2))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,2),0,:) & + + x%QT (DOF_BE(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BE(K,1),0,:) + ... + END DO + END DO +``` + +**解释:** + +1. **`p%TwistedSF(K,dim,mode,J,1)`**: 这里的 `TwistedSF` 带有 `1` 作为最后一个索引,表示这是**旋转形状函数**(或模态斜率/扭转形状函数),而不是位移形状函数。它描述了在给定模态下,叶片沿展向不同位置的**单位旋转量**。 +2. **`x%QDT(...)`**: `x%QDT` 包含了广义速度(模态坐标的时间导数)。 +3. **`AngVelHM`**: 这是叶片节点 `J` 相对于轮毂 (H) 的弹性角速度。它通过模态速度 `x%QDT` 乘以旋转形状函数来计算。 +4. **`AngPosHM`**: 这是叶片节点 `J` 相对于轮毂 (H) 的弹性角位置。它通过模态坐标 `x%QT` 乘以旋转形状函数来计算。 + +**叶片变形量(位移和旋转)的获取:** + +如果您想获取叶片上某个节点 `J` 的**总变形位移**和**总变形旋转**,您需要: + +1. **位移**: + * 从 `RtHSdat%rS(:,K,J)` 中减去叶片 `K` 节点 `J` 的**初始预弯位置**(即在 `x%QT` 都为零时的位置)。 + * `RtHSdat%rS(:,K,J)` 已经是相对于惯性坐标系的总位置。 + * **相对变形位移**:`RtHSdat%rS0S(:,K,J)` 已经包含了相对于叶片根部的变形位移(包括柔性变形和轴向缩短)。如果您需要相对于**预弯构型**的纯柔性变形,那么 `RtHSdat%rS0S(:,K,J)` 的计算结果就是这个。 +2. **旋转**: + * `RtHSdat%AngPosHM(:,K,J)` 直接提供了叶片节点 `J` 相对于轮毂的**弹性角位置**(即弹性旋转变形量)。这通常是相对于预弯构型的额外旋转。 + * `RtHSdat%AngVelEM(:,J,K)` 提供了叶片节点 `J` 在惯性坐标系中的总角速度,其中包含了轮毂的刚体运动和叶片的弹性变形引起的角速度。 + +**总结:** + +当结构上使用预弯的叶片模型和网格时,OpenFAST 已经将预弯几何信息编码在模态形状函数 `p%TwistedSF` 和 `p%AxRedBld` 中。 + +* `CalculatePositions` 通过将模态坐标 `x%QT` 与位移模态形状函数 `p%TwistedSF(...,0)` 叠加,并考虑轴向缩短效应 `p%AxRedBld`,来计算叶片节点相对于其根部的**变形位移**。这个位移是相对于**预弯构型**的柔性变形。 +* `CalculateAngularPosVelPAcc` 通过将模态坐标 `x%QT` 与旋转模态形状函数 `p%TwistedSF(...,1)` 叠加,来计算叶片节点相对于轮毂的**弹性角位置(旋转变形量)**。 + +因此,您不需要额外处理预弯,因为模态形状函数已经包含了预弯的影响。`x%QT` 中的模态坐标直接驱动了相对于预弯构型的柔性变形。 +[Timestamp: 2026/01/21 14:35:31] + +**user**: 我当前模态叠加的技术路线,支持叶片预弯变形,在模态形状的使用方法上是否有区别 +[Timestamp: 2026/01/21 14:42:16] + +**ai**: 如果您当前的模态叠加技术路线支持叶片预弯变形,那么在模态形状的使用方法上,**核心原理没有区别,但模态形状的生成方式和物理含义会包含预弯信息**。 + +让我们详细分析一下: + +### 1. 模态叠加法的核心原理 + +模态叠加法的基本思想是将结构的任意变形表示为一系列预定义的**模态形状**(或振型)的线性组合。每个模态形状乘以一个随时间变化的**模态坐标**(或广义坐标),然后将这些乘积相加,得到结构的瞬时变形。 + +$ \vec{u}(s, t) = \sum_{i=1}^{N} q_i(t) \vec{\phi}_i(s) $ + +其中: +* $ \vec{u}(s, t) $ 是叶片沿展向位置 $s$ 在时间 $t$ 的变形位移。 +* $ q_i(t) $ 是第 $i$ 阶模态的模态坐标(广义坐标),由仿真求解得到。 +* $ \vec{\phi}_i(s) $ 是第 $i$ 阶模态在展向位置 $s$ 处的模态形状向量。 + +### 2. 模态形状中包含预弯信息 + +当您的结构模型(例如,用于有限元分析生成模态的几何模型)本身就包含了叶片的预弯几何时,生成的模态形状 $ \vec{\phi}_i(s) $ 会自然地反映这种预弯。 + +这意味着: + +* **参考构型**: 此时,叶片的“未变形”或“零模态坐标”状态,就是其**预弯后的几何形状**。 +* **模态形状的物理含义**: 模态形状 $ \vec{\phi}_i(s) $ 描述的是叶片在**预弯构型基础上**的**柔性变形**。例如,第一阶挥舞模态描述的是叶片在预弯状态下,如何进一步向上或向下弯曲。 +* **`p%TwistedSF` 的作用**: 在 OpenFAST 的 `CalculatePositions` 子程序中,`p%TwistedSF` 数组就是这些模态形状函数。如果您的输入模型是预弯的,那么这些 `p%TwistedSF` 值就是从预弯叶片模型中提取或计算得到的。它们已经包含了预弯对模态形状的影响。 + +### 3. 模态形状使用方法的区别(概念上而非代码实现上) + +从代码实现的角度来看,`CalculatePositions` 和 `CalculateAngularPosVelPAcc` 子程序中模态形状 (`p%TwistedSF`) 的使用方式**没有区别**。它们仍然是将模态坐标 (`x%QT`) 乘以相应的模态形状函数来计算位移和旋转。 + +**然而,在概念和数据准备上存在关键区别:** + +* **传统直叶片模型**: + * 模态形状 $ \vec{\phi}_i(s) $ 是基于**直叶片**的参考构型计算的。 + * 预弯效应通常需要通过**额外的几何变换**或**初始位移**来引入,或者在气动网格中直接使用预弯几何。 + * `x%QT` 乘以 $ \vec{\phi}_i(s) $ 得到的是相对于**直叶片构型**的变形。 + +* **预弯叶片模型**: + * 模态形状 $ \vec{\phi}_i(s) $ 是基于**预弯叶片**的参考构型计算的。 + * 预弯效应**已经内嵌在模态形状中**,不需要额外的几何变换来引入预弯。 + * `x%QT` 乘以 $ \vec{\phi}_i(s) $ 得到的是相对于**预弯叶片构型**的**柔性变形**。 + +**这意味着:** + +1. **模态形状的生成**: 您需要确保用于生成 `p%TwistedSF` 和 `p%AxRedBld` 等参数的有限元模型(或等效梁模型)本身就包含了叶片的预弯几何。这是最关键的一步。 +2. **“零变形”状态**: 当所有模态坐标 `x%QT` 都为零时,叶片的位置将是其**预弯后的初始几何形状**,而不是完全笔直的。 +3. **变形的解释**: 此时,通过模态叠加计算出的位移和旋转,是叶片在**预弯构型基础上**的**额外柔性变形**。 + +### 总结 + +如果您当前的模态叠加技术路线支持叶片预弯变形,并且您已经使用了包含预弯几何的结构模型来生成模态形状(`p%TwistedSF` 等),那么: + +* **代码中的模态形状使用方法不变**:`CalculatePositions` 和 `CalculateAngularPosVelPAcc` 中的计算公式保持不变。 +* **模态形状的物理含义不同**:这些模态形状本身已经包含了预弯的影响,它们描述的是相对于预弯构型的柔性变形。 +* **数据准备是关键**:确保输入的模态形状数据 (`p%TwistedSF`, `p%AxRedBld`) 是从预弯叶片模型中正确提取的。 + +这种方法是处理预弯叶片的一种常见且有效的方式,因为它将预弯视为结构初始几何的一部分,从而简化了后续的动力学计算。 +[Timestamp: 2026/01/21 14:42:27] \ No newline at end of file diff --git a/书籍/力学书籍/OpenFast/FASTKinetics/auto/Blade.md b/书籍/力学书籍/OpenFast/FASTKinetics/auto/Blade.md new file mode 100644 index 0000000..15ce885 --- /dev/null +++ b/书籍/力学书籍/OpenFast/FASTKinetics/auto/Blade.md @@ -0,0 +1,175 @@ + + +The distributed properties of blade 1 bring about generalized inertia forces and generalized active forces associated with blade elasticity, blade damping, blade weight, and blade aerodynamics. +叶片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) \quad (r = 1, 2, \ldots, 22) \tag{1} +$$ + +其中 +$$ +\mu^{B1}(r) = AdjBlMs^{B1} \cdot BMassDen^{B1}(r) \tag{2} +$$ + +$$ +m^{B1Tip} = TipMass(1) \tag{3} +$$ +or, + +$$ +F_{r}^{*}\big|_{B1} = -\int_{0}^{BldFlexL} \mu^{B1}(r) \, {}^E\boldsymbol{v}_{r}^{S1}(r) \cdot \left\{ +\begin{array}{l} +\left( \sum_{i=1}^{14} {}^{E}\boldsymbol{v}_{i}^{S1}(r) \ddot{q}_{i} \right) + \left( \sum_{i=16}^{18} {}^{E}\boldsymbol{v}_{i}^{S1}(r) \ddot{q}_{i} \right) + {}^{E}\boldsymbol{v}_{Teet}^{S1}(r) \ddot{q}_{Teet} \\ ++ \left[ \sum_{i=4}^{14} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(r) \right) \dot{q}_{i} \right] + \left[ \sum_{i=16}^{18} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(r) \right) \dot{q}_{i} \right] + \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{Teet}^{S1}(r) \right) \dot{q}_{Teet} +\end{array} +\right\} dr \\ +- m^{B1Tip} {}^{E}\boldsymbol{v}_{r}^{S1}(BldFlexL) \cdot \left\{ +\begin{array}{l} +\left( \sum_{i=1}^{14} {}^{E}\boldsymbol{v}_{i}^{S1}(BldFlexL) \ddot{q}_{i} \right) + \left( \sum_{i=16}^{18} {}^{E}\boldsymbol{v}_{i}^{S1}(BldFlexL) \ddot{q}_{i} \right) + {}^{E}\boldsymbol{v}_{Teet}^{S1}(BldFlexL) \ddot{q}_{Teet} \\ ++ \left[ \sum_{i=4}^{14} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(BldFlexL) \right) \dot{q}_{i} \right] + \left[ \sum_{i=16}^{18} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(BldFlexL) \right) \dot{q}_{i} \right] \\ ++ \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{Teet}^{S1}(BldFlexL) \right) \dot{q}_{Teet} +\end{array} +\right\} \quad (r = 1, 2, \ldots, 14; 16, 17, 18; Teet) \tag{4} +$$ + +因此, + +$$ +\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) \quad (\text{Row, Col} = 1,2,\ldots,14;16,17,18;22) \tag{5} +$$ + +$$ +\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\{ \left[ \sum_{i=4}^{14} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(r) \right) \dot{q}_{i} \right] + \left[ \sum_{i=16}^{18} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(r) \right) \dot{q}_{i} \right] + \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{Teet}^{S1}(r) \right) \dot{q}_{Teet} \right\} dr \\ +- m^{B1Tip} {}^{E}\boldsymbol{v}_{\text{Row}}^{S1}(BldFlexL) \cdot \left\{ \left[ \sum_{i=4}^{14} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(BldFlexL) \right) \dot{q}_{i} \right] + \left[ \sum_{i=16}^{18} \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{i}^{S1}(BldFlexL) \right) \dot{q}_{i} \right] + \frac{d}{dt} \left( {}^{E}\boldsymbol{v}_{Teet}^{S1}(BldFlexL) \right) \dot{q}_{Teet} \right\} \quad (\text{Row} = 1,2,\ldots,14;16,17,18;22) \tag{6} +$$ + + +$$ +F_{r}\big|_{ElasticB1} = -\frac{\partial V'^{B1}}{\partial q_r} \quad (r = 1, 2, \ldots, 22) \tag{7} +$$ +$$ +\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} \tag{8} +$$ + +where $k_{\ i j}^{\,\prime B I F}$ and $\boldsymbol{k\,}_{I I}^{\prime B I E}$ are the generalized stiffnesses of blade 1 in the local flap and local edge directions respectively when centrifugal-stiffening effects are not included as follows: +其中,$k_{ij}^{\,\prime BIF}$ 和 $\boldsymbol{k}_{II}^{\prime BIE}$ 分别为未考虑离心刚化效应时,叶片1在局部挥舞方向和局部摆振方向的广义刚度,具体如下: +$$ +{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 \quad (i, j = 1, 2) \tag{9} +$$ + +其中, + +$$ +EI^{B1F}(r) = AdjFlSt^{B1} \cdot FlpStff^{B1}(r) \tag{10} +$$ + + +$$ +{k'}_{11}^{B1E} = \int_{0}^{BldFlexL} EI^{B1E}(r) \left[ \frac{d^2 \phi_{1}^{B1E}(r)}{dr^2} \right]^2 dr \tag{11} +$$ + +其中, + +$$ +EI^{B1E}(r) = AdjEdSt^{B1} \cdot EdgStff^{B1}(r) \tag{12} +$$ + +Similarly, when using the Rayleigh damping technique where the damping is assumed proportional to the stiffness, then +同样,在使用瑞利阻尼技术(假设阻尼与刚度成正比)时,则 +$$ +\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} \tag{13} +$$ +where $\zeta_{i}^{B I F}$ and $\zeta_{i}^{B I E}$ represent the structural damping ratio of blade 1 for the $i^{\mathrm{th}}$ mode in the local flap and edge directions, $B l d F l D m p^{B 1}(i)/100$ and $B l d E d D m p^{B 1}\left(i\right)/100$ respectively. Also, ${f^{\prime}}_{i}^{B I F}$ and $\boldsymbol{f}_{\ i}^{\prime B I E}$ represent the natural frequency of blade 1 for the $i^{\mathrm{th}}$ mode in the local flap and edge directions respectively without centrifugal-stiffening effects. That is, +其中,$\zeta_{i}^{BIF}$ 和 $\zeta_{i}^{BIE}$ 分别代表叶片1在第 $i$ 阶模态下在**挥舞**方向和**摆振**方向的结构阻尼比,对应表达式为 $BldFlDmp^{B1}(i)/100$ 和 $BldEdDmp^{B1}(i)/100$。此外,${f^{\prime}}_{i}^{B I F}$ 和 $\boldsymbol{f}_{\ i}^{\prime B I E}$ 分别表示叶片1在第 $i$ 阶模态下,**不考虑离心刚度效应**时的**挥舞**方向和**摆振**方向的固有频率。也就是说, +$$ +f_i^{\prime B1F} = \frac{1}{2\pi} \sqrt{\frac{k_{ii}^{\prime B1F}}{m_{ii}^{\prime B1F}}} \tag{14} +$$ + +$$ +f_i^{\prime B1E} = \frac{1}{2\pi} \sqrt{\frac{k_{ii}^{\prime B1E}}{m_{ii}^{\prime B1E}}} \tag{15} +$$ + +where $m_{\ i i}^{\prime B I F}$ and $m_{\ i i}^{\prime B I E}$ represent the generalized mass of blade 1 for the $i^{\mathrm{th}}$ mode in the local flap and edge directions respectively without centrifugal-stiffening and tip mass effects as follows: +其中,$m_{ii}^{\prime BIF}$ 和 $m_{ii}^{\prime BIE}$ 分别表示在未考虑离心刚化和叶尖质量效应的情况下,第 $i$ 阶模态下叶片1在**挥舞方向**和**摆振方向**的广义质量,具体定义如下: +$$ +m_{ij}^{\prime B1F} = \int_{0}^{BldFlexL} \mu^{B1}(r) \phi_i^{B1F}(r) \phi_j^{B1F}(r) \, dr \quad (i, j = 1, 2) \tag{16} +$$ +$$ +m_{11}^{\prime B1E} = \int_{0}^{BldFlexL} \mu^{B1}(r) \left[ \phi_1^{B1E}(r) \right]^2 dr \tag{17} +$$ + +Thus +$$ +[C(q,t)]|_{ElasticB1} = 0 \quad \text{and} \quad [C(q,t)]|_{DampB1} = 0 \tag{18} +$$ + +$$ +\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} \tag{19} +$$ + +$$ +\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} \tag{20} +$$$$ +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 \quad (r = 3,4,\ldots,14;16,17,18;Teet)\tag{21} +$$ + +Thus, +$$ +[C(q,t)]|_{GravB1} = 0\tag{22} +$$ +$$ +\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 \quad (\text{Row} = 3, 4, \ldots, 14; 16, 17, 18; 22)\tag{23} +$$ + + +$$ +\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)(r = 1, 2, \ldots, 14; 16, 17, 18; Teet)\tag{24} +$$ + +where $F_{A e r o B 1}^{S 1}(r)$ and $M_{A e r o B 1}^{M 1}\left(r\right)$ are aerodynamic forces and pitching moments applied to point S1 on blade 1 respectively expressed per unit span. Note that $M_{A e r o B 1}^{M 1}\left(r\right)$ can include effects of both direct aerodynamic pitching moments (i.e., $\mathrm{Cm})$ ) and aerodynamic pitching moments caused by an aerodynamic offset (i.e., moments due to aerodynamic lift and drag forces acting at a distance away from the center of mass of the blade element along the aerodynamic chord). +其中,$F_{\text{AeroB1}}^{S1}(r)$ 和 $M_{\text{AeroB1}}^{M1}(r)$ 分别表示作用于叶片1上点S1处的单位展向长度上的气动力和气动俯仰力矩。需要注意的是,$M_{\text{AeroB1}}^{M1}(r)$ 可包含两部分气动俯仰力矩的影响:一是直接气动俯仰力矩(即 $\mathrm{Cm}$),二是由气动力(升力和阻力)在叶片元素气动弦线上相对于质心产生的偏移距离所引起的气动俯仰力矩。 +$$ +[C(q,t)]|_{AeroB1} = 0\tag{25} +$$ + +$$ +\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) \quad (\text{Row} = 1, 2, \ldots, 14; 16, 17, 18; 22)\tag{26} +$$ \ No newline at end of file diff --git a/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculateAngularPosVelPAcc.md b/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculateAngularPosVelPAcc.md new file mode 100644 index 0000000..66797e5 --- /dev/null +++ b/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculateAngularPosVelPAcc.md @@ -0,0 +1,222 @@ + + +```fortran +SUBROUTINE CalculateAngularPosVelPAcc( p, x, CoordSys, RtHSdat ) +!.................................................................................................................................. + + ! Passed variables + TYPE(ED_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(ED_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(ED_CoordSys), INTENT(IN ) :: CoordSys !< The coordinate systems that have been set for these states/time + TYPE(ED_RtHndSide), INTENT(INOUT) :: RtHSdat !< data from the RtHndSid module (contains positions to be set) + + !Local variables + + REAL(ReKi) :: AngVelHM (3) ! Angular velocity of eleMent J of blade K (body M) in the hub (body H). +! REAL(ReKi) :: AngVelEN (3) ! Angular velocity of the nacelle (body N) in the inertia frame (body E for earth). + REAL(ReKi) :: AngAccELt (3) ! Portion of the angular acceleration of the low-speed shaft (body L) in the inertia frame (body E for earth) associated with everything but the QD2T()'s. + INTEGER(IntKi) :: J ! Counter for elements + INTEGER(IntKi) :: K ! Counter for blades + + !------------------------------------------------------------------------------------------------- + ! Angular and partial angular velocities + !------------------------------------------------------------------------------------------------- + + ! Define the angular and partial angular velocities of all of the rigid bodies in the inertia frame: + ! NOTE: PAngVelEN(I,D,:) = the Dth-derivative of the partial angular velocity of DOF I for body N in body E. + + RtHSdat%PAngVelEX( :,0,:) = 0.0 + RtHSdat%PAngVelEX(DOF_R ,0,:) = CoordSys%z1 + RtHSdat%PAngVelEX(DOF_P ,0,:) = -CoordSys%z3 + RtHSdat%PAngVelEX(DOF_Y ,0,:) = CoordSys%z2 + RtHSdat%AngVelEX = x%QDT(DOF_R )*RtHSdat%PAngVelEX(DOF_R ,0,:) & + + x%QDT(DOF_P )*RtHSdat%PAngVelEX(DOF_P ,0,:) & + + x%QDT(DOF_Y )*RtHSdat%PAngVelEX(DOF_Y ,0,:) + RtHSdat%AngPosEX = x%QT (DOF_R )*RtHSdat%PAngVelEX(DOF_R ,0,:) & + + x%QT (DOF_P )*RtHSdat%PAngVelEX(DOF_P ,0,:) & + + x%QT (DOF_Y )*RtHSdat%PAngVelEX(DOF_Y ,0,:) + + RtHSdat%PAngVelEB( :,0,:) = RtHSdat%PAngVelEX(:,0,:) + RtHSdat%PAngVelEB(DOF_TFA1,0,:) = -p%TwrFASF(1,p%TTopNode,1)*CoordSys%a3 + RtHSdat%PAngVelEB(DOF_TSS1,0,:) = p%TwrSSSF(1,p%TTopNode,1)*CoordSys%a1 + RtHSdat%PAngVelEB(DOF_TFA2,0,:) = -p%TwrFASF(2,p%TTopNode,1)*CoordSys%a3 + RtHSdat%PAngVelEB(DOF_TSS2,0,:) = p%TwrSSSF(2,p%TTopNode,1)*CoordSys%a1 + RtHSdat%AngVelEB = RtHSdat%AngVelEX + x%QDT(DOF_TFA1)*RtHSdat%PAngVelEB(DOF_TFA1,0,:) & + + x%QDT(DOF_TSS1)*RtHSdat%PAngVelEB(DOF_TSS1,0,:) & + + x%QDT(DOF_TFA2)*RtHSdat%PAngVelEB(DOF_TFA2,0,:) & + + x%QDT(DOF_TSS2)*RtHSdat%PAngVelEB(DOF_TSS2,0,:) + RtHSdat%AngPosXB = x%QT (DOF_TFA1)*RtHSdat%PAngVelEB(DOF_TFA1,0,:) & + + x%QT (DOF_TSS1)*RtHSdat%PAngVelEB(DOF_TSS1,0,:) & + + x%QT (DOF_TFA2)*RtHSdat%PAngVelEB(DOF_TFA2,0,:) & + + x%QT (DOF_TSS2)*RtHSdat%PAngVelEB(DOF_TSS2,0,:) + + RtHSdat%PAngVelEN( :,0,:)= RtHSdat%PAngVelEB(:,0,:) + RtHSdat%PAngVelEN(DOF_Yaw ,0,:)= CoordSys%d2 + RtHSdat%AngVelEN = RtHSdat%AngVelEB + x%QDT(DOF_Yaw )*RtHSdat%PAngVelEN(DOF_Yaw ,0,:) + + RtHSdat%PAngVelER( :,0,:)= RtHSdat%PAngVelEN(:,0,:) + RtHSdat%PAngVelER(DOF_RFrl,0,:)= CoordSys%rfa + RtHSdat%AngVelER = RtHSdat%AngVelEN + x%QDT(DOF_RFrl)*RtHSdat%PAngVelER(DOF_RFrl,0,:) + + RtHSdat%PAngVelEL( :,0,:)= RtHSdat%PAngVelER(:,0,:) + RtHSdat%PAngVelEL(DOF_GeAz,0,:)= CoordSys%c1 + RtHSdat%PAngVelEL(DOF_DrTr,0,:)= CoordSys%c1 + RtHSdat%AngVelEL = RtHSdat%AngVelER + x%QDT(DOF_GeAz)*RtHSdat%PAngVelEL(DOF_GeAz,0,:) & + + x%QDT(DOF_DrTr)*RtHSdat%PAngVelEL(DOF_DrTr,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 + + RtHSdat%PAngVelEG( :,0,:) = RtHSdat%PAngVelER(:,0,:) + RtHSdat%PAngVelEG(DOF_GeAz,0,:) = p%GBRatio*CoordSys%c1 + RtHSdat%AngVelEG = RtHSdat%AngVelER + x%QDT(DOF_GeAz)*RtHSdat%PAngVelEG(DOF_GeAz,0,:) + + RtHSdat%PAngVelEA( :,0,:) = RtHSdat%PAngVelEN(:,0,:) + RtHSdat%PAngVelEA(DOF_TFrl,0,:) = CoordSys%tfa + RtHSdat%AngVelEA = RtHSdat%AngVelEN + x%QDT(DOF_TFrl)*RtHSdat%PAngVelEA(DOF_TFrl,0,:) + + + + ! Define the 1st derivatives of the partial angular velocities of all + ! of the rigid bodies in the inertia frame and the portion of the angular + ! acceleration of the rigid bodies in the inertia frame associated with + ! everything but the QD2T()'s: + + RtHSdat%PAngVelEX( :,1,:) = 0.0 + RtHSdat%AngAccEXt = 0.0 + + RtHSdat%PAngVelEB( :,1,:) = RtHSdat%PAngVelEX(:,1,:) + RtHSdat%PAngVelEB(DOF_TFA1,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX, RtHSdat%PAngVelEB(DOF_TFA1,0,:) ) + RtHSdat%PAngVelEB(DOF_TSS1,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX, RtHSdat%PAngVelEB(DOF_TSS1,0,:) ) + RtHSdat%PAngVelEB(DOF_TFA2,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX, RtHSdat%PAngVelEB(DOF_TFA2,0,:) ) + RtHSdat%PAngVelEB(DOF_TSS2,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX, RtHSdat%PAngVelEB(DOF_TSS2,0,:) ) + RtHSdat%AngAccEBt = RtHSdat%AngAccEXt + x%QDT(DOF_TFA1)*RtHSdat%PAngVelEB(DOF_TFA1,1,:) & + + x%QDT(DOF_TSS1)*RtHSdat%PAngVelEB(DOF_TSS1,1,:) & + + x%QDT(DOF_TFA2)*RtHSdat%PAngVelEB(DOF_TFA2,1,:) & + + x%QDT(DOF_TSS2)*RtHSdat%PAngVelEB(DOF_TSS2,1,:) + + RtHSdat%PAngVelEN( :,1,:) = RtHSdat%PAngVelEB(:,1,:) + RtHSdat%PAngVelEN(DOF_Yaw ,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEB, RtHSdat%PAngVelEN(DOF_Yaw ,0,:) ) + RtHSdat%AngAccENt = RtHSdat%AngAccEBt + x%QDT(DOF_Yaw )*RtHSdat%PAngVelEN(DOF_Yaw ,1,:) + + RtHSdat%PAngVelER( :,1,:) = RtHSdat%PAngVelEN(:,1,:) + RtHSdat%PAngVelER(DOF_RFrl,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEN, RtHSdat%PAngVelER(DOF_RFrl,0,:) ) + RtHSdat%AngAccERt = RtHSdat%AngAccENt + x%QDT(DOF_RFrl)*RtHSdat%PAngVelER(DOF_RFrl,1,:) + + RtHSdat%PAngVelEL( :,1,:) = RtHSdat%PAngVelER(:,1,:) + RtHSdat%PAngVelEL(DOF_GeAz,1,:) = CROSS_PRODUCT( RtHSdat%AngVelER, RtHSdat%PAngVelEL(DOF_GeAz,0,:) ) + RtHSdat%PAngVelEL(DOF_DrTr,1,:) = CROSS_PRODUCT( RtHSdat%AngVelER, RtHSdat%PAngVelEL(DOF_DrTr,0,:) ) + AngAccELt = RtHSdat%AngAccERt + x%QDT(DOF_GeAz)*RtHSdat%PAngVelEL(DOF_GeAz,1,:) & + + x%QDT(DOF_DrTr)*RtHSdat%PAngVelEL(DOF_DrTr,1,:) + + RtHSdat%PAngVelEH( :,1,:) = RtHSdat%PAngVelEL(:,1,:) + RtHSdat%AngAccEHt = AngAccELt +IF ( p%NumBl == 2 ) THEN ! 2-blader + RtHSdat%PAngVelEH(DOF_Teet,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEH, RtHSdat%PAngVelEH(DOF_Teet,0,:) ) + RtHSdat%AngAccEHt = RtHSdat%AngAccEHt + x%QDT(DOF_Teet)*RtHSdat%PAngVelEH(DOF_Teet,1,:) +ENDIF + + RtHSdat%PAngVelEG( :,1,:) = RtHSdat%PAngVelER(:,1,:) + RtHSdat%PAngVelEG(DOF_GeAz,1,:) = CROSS_PRODUCT( RtHSdat%AngVelER, RtHSdat%PAngVelEG(DOF_GeAz,0,:) ) + RtHSdat%AngAccEGt = RtHSdat%AngAccERt + x%QDT(DOF_GeAz)*RtHSdat%PAngVelEG(DOF_GeAz,1,:) + + RtHSdat%PAngVelEA( :,1,:) = RtHSdat%PAngVelEN(:,1,:) + RtHSdat%PAngVelEA(DOF_TFrl,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEN, RtHSdat%PAngVelEA(DOF_TFrl,0,:) ) + RtHSdat%AngAccEAt = RtHSdat%AngAccENt + x%QDT(DOF_TFrl)*RtHSdat%PAngVelEA(DOF_TFrl,1,:) + + + + DO K = 1,p%NumBl ! Loop through all blades + + DO J = 0,p%TipNode ! Loop through the blade nodes / elements + ! Define the partial angular velocities of the current node (body M(RNodes(J))) in the inertia frame: + ! NOTE: PAngVelEM(K,J,I,D,:) = the Dth-derivative of the partial angular velocity + ! of DOF I for body M of blade K, element J in body E. + + 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,:) + 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%AngPosHM(:,K,J ) = x%QT (DOF_BF(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,1),0,:) & + + x%QT (DOF_BF(K,2))*RtHSdat%PAngVelEM(K,J,DOF_BF(K,2),0,:) & + + x%QT (DOF_BE(K,1))*RtHSdat%PAngVelEM(K,J,DOF_BE(K,1),0,:) + 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,:) + + ! Define the 1st derivatives of the partial angular velocities of the current node (body M(RNodes(J))) in the inertia frame: + + ! NOTE: These are currently unused by the code, therefore, they need not + ! be calculated. Thus, they are currently commented out. If it + ! turns out that they are ever needed (i.e., if inertias of the + ! blade elements are ever added, etc...) simply uncomment out these computations: + ! 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,:) ) + + + END DO !J = 1,p%BldNodes ! Loop through the blade nodes / elements + + END DO !K = 1,p%NumBl + + + !............... + ! tower values: + !............... + + DO J = 0,p%TwrNodes ! Loop through the tower nodes / elements + + ! Define the partial angular velocities (and their 1st derivatives) of the + ! current node (body F(HNodes(J)) in the inertia frame. + ! Also define the overall angular velocity of the current node in the inertia frame. + ! Also, define the portion of the angular acceleration of the current node + ! in the inertia frame associated with everything but the QD2T()'s: + + ! NOTE: PAngVelEF(J,I,D,:) = the Dth-derivative of the partial angular velocity + ! of DOF I for body F of element J in body E. + + RtHSdat%PAngVelEF (J, :,0,:) = RtHSdat%PAngVelEX(:,0,:) + RtHSdat%PAngVelEF (J,DOF_TFA1,0,:) = -p%TwrFASF(1,J,1)*CoordSys%a3 + RtHSdat%PAngVelEF (J,DOF_TSS1,0,:) = p%TwrSSSF(1,J,1)*CoordSys%a1 + RtHSdat%PAngVelEF (J,DOF_TFA2,0,:) = -p%TwrFASF(2,J,1)*CoordSys%a3 + RtHSdat%PAngVelEF (J,DOF_TSS2,0,:) = p%TwrSSSF(2,J,1)*CoordSys%a1 + + RtHSdat%PAngVelEF (J, :,1,:) = RtHSdat%PAngVelEX(:,1,:) + RtHSdat%PAngVelEF (J,DOF_TFA1,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TFA1,0,:) ) + RtHSdat%PAngVelEF (J,DOF_TSS1,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TSS1,0,:) ) + RtHSdat%PAngVelEF (J,DOF_TFA2,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TFA2,0,:) ) + RtHSdat%PAngVelEF (J,DOF_TSS2,1,:) = CROSS_PRODUCT( RtHSdat%AngVelEX , RtHSdat%PAngVelEF(J,DOF_TSS2,0,:) ) + + + RtHSdat%AngVelEF (:,J) = RtHSdat%AngVelEX + x%QDT(DOF_TFA1)*RtHSdat%PAngVelEF(J,DOF_TFA1,0,:) & + + x%QDT(DOF_TSS1)*RtHSdat%PAngVelEF(J,DOF_TSS1,0,:) & + + x%QDT(DOF_TFA2)*RtHSdat%PAngVelEF(J,DOF_TFA2,0,:) & + + x%QDT(DOF_TSS2)*RtHSdat%PAngVelEF(J,DOF_TSS2,0,:) + + RtHSdat%AngPosXF (:,J) = x%QT (DOF_TFA1)*RtHSdat%PAngVelEF(J,DOF_TFA1,0,:) & + + x%QT (DOF_TSS1)*RtHSdat%PAngVelEF(J,DOF_TSS1,0,:) & + + x%QT (DOF_TFA2)*RtHSdat%PAngVelEF(J,DOF_TFA2,0,:) & + + x%QT (DOF_TSS2)*RtHSdat%PAngVelEF(J,DOF_TSS2,0,:) + RtHSdat%AngPosEF (:,J) = RtHSdat%AngPosEX + RtHSdat%AngPosXF(:,J) + RtHSdat%AngAccEFt(:,J) = RtHSdat%AngAccEXt + x%QDT(DOF_TFA1)*RtHSdat%PAngVelEF(J,DOF_TFA1,1,:) & + + x%QDT(DOF_TSS1)*RtHSdat%PAngVelEF(J,DOF_TSS1,1,:) & + + x%QDT(DOF_TFA2)*RtHSdat%PAngVelEF(J,DOF_TFA2,1,:) & + + x%QDT(DOF_TSS2)*RtHSdat%PAngVelEF(J,DOF_TSS2,1,:) + + END DO ! J + + +END SUBROUTINE CalculateAngularPosVelPAcc +``` \ No newline at end of file diff --git a/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculateForcesMoments.md b/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculateForcesMoments.md new file mode 100644 index 0000000..4aa1426 --- /dev/null +++ b/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculateForcesMoments.md @@ -0,0 +1,634 @@ + +```fortran +SUBROUTINE CalculateForcesMoments( p, x, CoordSys, u, RtHSdat ) +!.................................................................................................................................. + + ! Passed variables + TYPE(ED_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(ED_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(ED_CoordSys), INTENT(IN ) :: CoordSys !< The coordinate systems that have been set for these states/time + TYPE(ED_InputType), INTENT(IN ) :: u !< The aero (blade) & nacelle forces/moments + TYPE(ED_RtHndSide), INTENT(INOUT) :: RtHSdat !< data from the RtHndSid module (contains positions to be set) + + ! Local variables + REAL(ReKi) :: TmpVec (3) ! A temporary vector used in various computations. + REAL(ReKi) :: TmpVec1 (3) ! A temporary vector used in various computations. + REAL(ReKi) :: TmpVec2 (3) ! A temporary vector used in various computations. + REAL(ReKi) :: TmpVec3 (3) ! A temporary vector used in various computations. + REAL(ReKi) :: TmpVec4 (3) ! A temporary vector used in various computations. + REAL(ReKi) :: TmpVec5 (3) ! A temporary vector used in various computations. + REAL(ReKi) :: Force(3) ! External force (e.g. from AeroDyn) + REAL(ReKi) :: Moment(3) ! External moment (e.g. from AeroDyn) + 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) :: NodeNum ! Node number for blade element (on a single mesh) + +!..................................... +! Compute forces and moments from properties related to Aero inputs +!FSTipDrag +!FSAero and MMAero +!..................................... + DO K = 1,p%NumBl ! Loop through all blades + + ! 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) ) + RtHSdat%FSTipDrag = 0.0_ReKi ! Calculate the tip drag forces if necessary + + + ! Calculate the normal and tangential aerodynamic forces and the aerodynamic + ! pitching moment at the current element per unit span by calling AeroDyn, + ! if necessary: + + DO J = 1,p%BldNodes ! Loop through the blade nodes / elements + + + ! Calculate the aerodynamic pitching moment arm (i.e., the position vector + ! from point S on the blade to the aerodynamic center of the element): + + RtHSdat%rSAerCen(:,J,K) = p%rSAerCenn1(K,J)*CoordSys%n1(K,J,:) + p%rSAerCenn2(K,J)*CoordSys%n2(K,J,:) + +! rPAerCen = m%RtHS%rPQ + m%RtHS%rQS(:,K,J) + m%RtHS%rSAerCen(:,J,K) ! Position vector from teeter pin (point P) to blade analysis node aerodynamic center. +! rAerCen = m%RtHS%rS (:,K,J) + m%RtHS%rSAerCen(:,J,K) ! Position vector from inertial frame origin to blade analysis node aerodynamic center. + + + ! fill FSAero() and MMAero() with the forces resulting from inputs u%BladeLn2Mesh(K)%Force(1:2,:) and u%BladeLn2Mesh(K)%Moment(3,:): + ! [except, we're ignoring the additional nodes we added on the mesh end points] + + NodeNum = J ! we're ignoring the root and tip + + 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 + RtHSdat%FSAero(1,K,J) = u%BladePtLoads(K)%Force(1,NodeNum) / p%DRNodes(J) + RtHSdat%FSAero(2,K,J) = u%BladePtLoads(K)%Force(3,NodeNum) / p%DRNodes(J) + RtHSdat%FSAero(3,K,J) = -u%BladePtLoads(K)%Force(2,NodeNum) / p%DRNodes(J) + + RtHSdat%MMAero(1,K,J) = u%BladePtLoads(K)%Moment(1,NodeNum) / p%DRNodes(J) + RtHSdat%MMAero(2,K,J) = u%BladePtLoads(K)%Moment(3,NodeNum) / p%DRNodes(J) + RtHSdat%MMAero(3,K,J) = -u%BladePtLoads(K)%Moment(2,NodeNum) / p%DRNodes(J) + end if + + + END DO !J + END DO ! K + + +!..................................... +! PFrcS0B and PMomH0B +!..................................... +! RtHSdat%PFrcS0B = 0.0 +! RtHSdat%PMomH0B = 0.0 +DO K = 1,p%NumBl ! Loop through all blades + + ! Initialize the partial forces and moments (including those associated + ! with the QD2T()'s and those that are not) at the blade root (point S(0)) + ! using the tip brake effects: + + RtHSdat%PFrcS0B(:,K,:) = 0.0 ! Initialize these partial + RtHSdat%PMomH0B(:,K,:) = 0.0 ! forces and moments to zero + DO I = 1,p%DOFs%NPSE(K) ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of blade K + + TmpVec1 = -p%TipMass(K)*RtHSdat%PLinVelES(K,p%TipNode,p%DOFs%PSE(K,I),0,:) ! The portion of PFrcS0B associated with the tip brake + + 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 ) ! The portion of PMomH0B associated with the tip brake + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of blade K + + + DO J = 1,p%BldNodes ! Loop through the blade nodes / elements + + ! Integrate to find the partial forces and moments (including those associated + ! with the QD2T()'s and those that are not) at the blade root (point S(0)): + + DO I = 1,p%DOFs%NPSE(K) ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of blade K + + TmpVec1 = -p%BElmntMass(J,K)*RtHSdat%PLinVelES(K,J,p%DOFs%PSE(K,I),0,:) ! The portion of PFrcS0B associated with blade element J + + 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 ) ! The portion of PMomH0B associated with blade element J + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of blade K + END DO + + + END DO + + +!..................................... +! FrcS0Bt and MomH0Bt +!..................................... + DO K = 1,p%NumBl ! Loop through all blades + + TmpVec1 = RtHSdat%FSTipDrag(:,K) - p%TipMass(K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,p%TipNode) ) ! The portion of FrcS0Bt associated with the tip brake + RtHSdat%FrcS0Bt(:,K) = TmpVec1 + RtHSdat%MomH0Bt(:,K) = CROSS_PRODUCT( RtHSdat%rS0S(:,K,p%TipNode), TmpVec1 ) ! The portion of MomH0Bt associated with the tip brake + + DO J = 1,p%BldNodes ! Loop through the blade nodes / elements + + TmpVec1 = RtHSdat%FSAero(:,K,J)*p%DRNodes(J) - p%BElmntMass(J,K)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccESt(:,K,J) ) ! The portion of FrcS0Bt associated with blade element J + TmpVec2 = CROSS_PRODUCT( RtHSdat%rS0S(:,K,J), TmpVec1 ) ! The portion of MomH0Bt associated with blade element J + TmpVec3 = RtHSdat%MMAero(:,K,J)*p%DRNodes(J) ! The total external moment applied to blade element J + + RtHSdat%FrcS0Bt(:,K) = RtHSdat%FrcS0Bt(:,K) + TmpVec1 + RtHSdat%MomH0Bt(:,K) = RtHSdat%MomH0Bt(:,K) + TmpVec2 + TmpVec3 + + END DO !J + + END DO !K + + +!..................................... +! PFrcPRot AND PMomLPRot: +! ( requires PFrcS0B and PMomH0B) +!..................................... + ! Initialize the partial forces and moments (including those associated + ! with the QD2T()'s and those that are not) at the teeter pin (point P) using the hub mass effects: + + RtHSdat%PFrcPRot = 0.0 ! Initialize these partial + RtHSdat%PMomLPRot = 0.0 ! forces and moments to zero + DO I = 1,p%DOFs%NPCE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the hub center of mass (point C) + + TmpVec1 = -p%HubMass*RtHSdat%PLinVelEC(p%DOFs%PCE(I),0,:) ! The portion of PFrcPRot associated with the HubMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rPC, TmpVec1 ) ! The portion of PMomLPRot associated with the HubMass + + RtHSdat%PFrcPRot (:,p%DOFs%PCE(I)) = TmpVec1 + RtHSdat%PMomLPRot(:,p%DOFs%PCE(I)) = TmpVec2 - p%Hubg1Iner*CoordSys%g1*DOT_PRODUCT( CoordSys%g1, RtHSdat%PAngVelEH(p%DOFs%PCE(I),0,:) ) & + - p%Hubg2Iner*CoordSys%g2*DOT_PRODUCT( CoordSys%g2, RtHSdat%PAngVelEH(p%DOFs%PCE(I),0,:) ) + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the hub center of mass (point C) + + + DO K = 1,p%NumBl ! Loop through all blades + + ! Calculate the position vector from the teeter pin to the blade root: + + !rPS0(:,K) = RtHSdat%rPQ + p%HubRad*CoordSys%j3(K,:) ! Position vector from teeter pin (point P) to blade root (point S(0)). + + ! Add the blade effects to the partial forces and moments (including those associated with the QD2T()'s and those that are + ! not) at the teeter pin (point P): + + DO I = 1,p%DOFs%NPSE(K) ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of blade K + + TmpVec = CROSS_PRODUCT( RtHSdat%rPS0(:,K), RtHSdat%PFrcS0B(:,K,p%DOFs%PSE(K,I)) ) ! The portion of PMomLPRot associated with PFrcS0B. + + RtHSdat%PFrcPRot (:,p%DOFs%PSE(K,I)) = RtHSdat%PFrcPRot (:,p%DOFs%PSE(K,I)) + RtHSdat%PFrcS0B(:,K,p%DOFs%PSE(K,I)) + RtHSdat%PMomLPRot(:,p%DOFs%PSE(K,I)) = RtHSdat%PMomLPRot(:,p%DOFs%PSE(K,I)) + RtHSdat%PMomH0B(:,K,p%DOFs%PSE(K,I))+TmpVec + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of blade K + + + END DO ! K + !PRINT '(F30.20)', RtHSdat%PMomLPRot(:,11) +!..................................... +! FrcPRott and MomLPRott: +! (requires FrcS0Bt and MomH0Bt) +!..................................... + + TmpVec1 = -p%HubMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccECt ) ! The portion of FrcPRott associated with the HubMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rPC, TmpVec1 ) ! The portion of MomLPRott associated with the HubMass + TmpVec = p%Hubg1Iner*CoordSys%g1*DOT_PRODUCT( CoordSys%g1, RtHSdat%AngVelEH ) & ! = ( Hub inertia dyadic ) dot ( angular velocity of hub in the inertia frame ) + + p%Hubg2Iner*CoordSys%g2*DOT_PRODUCT( CoordSys%g2, RtHSdat%AngVelEH ) + TmpVec3 = CROSS_PRODUCT( -RtHSdat%AngVelEH, TmpVec ) ! = ( -angular velocity of hub in the inertia frame ) cross ( TmpVec ) + + RtHSdat%FrcPRott(1) = TmpVec1(1) + u%HubPtLoad%Force(1,1) + RtHSdat%FrcPRott(2) = TmpVec1(2) + u%HubPtLoad%Force(3,1) + RtHSdat%FrcPRott(3) = TmpVec1(3) - u%HubPtLoad%Force(2,1) + + RtHSdat%MomLPRott = TmpVec2 + TmpVec3 - p%Hubg1Iner*CoordSys%g1*DOT_PRODUCT( CoordSys%g1, RtHSdat%AngAccEHt ) & + - p%Hubg2Iner*CoordSys%g2*DOT_PRODUCT( CoordSys%g2, RtHSdat%AngAccEHt ) + + RtHSdat%MomLPRott(1) = RtHSdat%MomLPRott(1) + u%HubPtLoad%Moment(1,1) + RtHSdat%MomLPRott(2) = RtHSdat%MomLPRott(2) + u%HubPtLoad%Moment(3,1) + RtHSdat%MomLPRott(3) = RtHSdat%MomLPRott(3) - u%HubPtLoad%Moment(2,1) + + DO K = 1,p%NumBl ! Loop through all blades + + ! Calculate the position vector from the teeter pin to the blade root: + + !rPS0 = RtHSdat%rPQ + p%HubRad*m%CoordSys%j3(K,:) ! Position vector from teeter pin (point P) to blade root (point S(0)). + + TmpVec = CROSS_PRODUCT( RtHSdat%rPS0(:,K), RtHSdat%FrcS0Bt(:,K) ) ! The portion of MomLPRott associated with FrcS0Bt. + + RtHSdat%FrcPRott = RtHSdat%FrcPRott + RtHSdat%FrcS0Bt(:,K) + RtHSdat%MomLPRott = RtHSdat%MomLPRott + RtHSdat%MomH0Bt(:,K) + TmpVec + + END DO ! K + + + ! Define the partial forces and moments (including those associated with + ! the QD2T()'s and those that are not) at the specified point on the + ! rotor-furl axis (point V) / nacelle (body N) using the structure that + ! furls with the rotor, generator, and rotor effects. + +!..................................... +! PMomNGnRt and PFrcVGnRt +! (requires PMomLPRot and PFrcPRot) +!..................................... + RtHSdat%PFrcVGnRt = RtHSdat%PFrcPRot ! Initialize these partial forces and + RtHSdat%PMomNGnRt = RtHSdat%PMomLPRot ! moments using the rotor effects + DO I = 1,p%DOFs%NActvDOF ! Loop through all active (enabled) DOFs + + TmpVec = CROSS_PRODUCT( RtHSdat%rVP, RtHSdat%PFrcPRot(:,p%DOFs%SrtPS(I)) ) ! The portion of PMomNGnRt associated with the PFrcPRot + + RtHSdat%PMomNGnRt(:,p%DOFs%SrtPS(I)) = RtHSdat%PMomNGnRt(:,p%DOFs%SrtPS(I)) + TmpVec + + ENDDO ! I - All active (enabled) DOFs + DO I = 1,p%DOFs%NPDE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the center of mass of the structure that furls with the rotor (not including rotor) (point D) + + TmpVec1 = -p%RFrlMass*RtHSdat%PLinVelED(p%DOFs%PDE(I) ,0,:) ! The portion of PFrcVGnRt associated with the RFrlMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rVD, TmpVec1 ) ! The portion of PMomNGnRt associated with the RFrlMass + + RtHSdat%PFrcVGnRt(:,p%DOFs%PDE(I) ) = RtHSdat%PFrcVGnRt(:,p%DOFs%PDE(I) ) + TmpVec1 + + RtHSdat%PMomNGnRt(:,p%DOFs%PDE(I) ) = RtHSdat%PMomNGnRt(:,p%DOFs%PDE(I) ) + TmpVec2 & + - p%RrfaIner*CoordSys%rfa*DOT_PRODUCT( CoordSys%rfa, RtHSdat%PAngVelER(p%DOFs%PDE(I) ,0,:) ) & + - p%GenIner*CoordSys%c1 *DOT_PRODUCT( CoordSys%c1 , RtHSdat%PAngVelEG(p%DOFs%PDE(I) ,0,:) ) + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the center of mass of the structure that furls with the rotor (not including rotor) (point D) + IF ( p%DOF_Flag(DOF_GeAz) ) THEN + + RtHSdat%PMomNGnRt(:,DOF_GeAz) = RtHSdat%PMomNGnRt(:,DOF_GeAz) & ! The previous loop (DO I = 1,NPDE) misses the DOF_GeAz-contribution to: ( Generator inertia dyadic ) dot ( partial angular velocity of the generator in the inertia frame ) + - p%GenIner*CoordSys%c1 *DOT_PRODUCT( CoordSys%c1, RtHSdat%PAngVelEG(DOF_GeAz,0,:) ) ! Thus, add this contribution if necessary. + + ENDIF + +!..................................... +! FrcVGnRtt and MomNGnRtt +! (requires FrcPRott and MomLPRott) +!..................................... + TmpVec1 = -p%RFrlMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEDt ) ! The portion of FrcVGnRtt associated with the RFrlMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rVD , TmpVec1 ) ! The portion of MomNGnRtt associated with the RFrlMass + TmpVec3 = CROSS_PRODUCT( RtHSdat%rVP , RtHSdat%FrcPRott ) ! The portion of MomNGnRtt associated with the FrcPRott + TmpVec = p%RrfaIner*CoordSys%rfa*DOT_PRODUCT( CoordSys%rfa, RtHSdat%AngVelER ) ! = ( R inertia dyadic ) dot ( angular velocity of structure that furls with the rotor in the inertia frame ) + TmpVec4 = CROSS_PRODUCT( -RtHSdat%AngVelER, TmpVec ) ! = ( -angular velocity of structure that furls with the rotor in the inertia frame ) cross ( TmpVec ) + TmpVec = p%GenIner*CoordSys%c1* DOT_PRODUCT( CoordSys%c1 , RtHSdat%AngVelEG ) ! = ( Generator inertia dyadic ) dot ( angular velocity of generator in the inertia frame ) + TmpVec5 = CROSS_PRODUCT( -RtHSdat%AngVelEG, TmpVec ) ! = ( -angular velocity of generator in the inertia frame ) cross ( TmpVec ) + + RtHSdat%FrcVGnRtt = RtHSdat%FrcPRott + TmpVec1 + RtHSdat%MomNGnRtt = RtHSdat%MomLPRott + TmpVec2 + TmpVec3 + TmpVec4 + TmpVec5 & + - p%RrfaIner*CoordSys%rfa*DOT_PRODUCT( CoordSys%rfa, RtHSdat%AngAccERt ) & + - p%GenIner*CoordSys%c1 *DOT_PRODUCT( CoordSys%c1 , RtHSdat%AngAccEGt ) + + +!..................................... +! PFrcWTail and PMomNTail +!..................................... + ! Define the partial forces and moments (including those associated with the QD2T()'s and + ! those that are not) at the specified point on the tail-furl axis (point W) / nacelle (body N) using the tail effects. + + RtHSdat%PFrcWTail = 0.0 ! Initialize these partial + RtHSdat%PMomNTail = 0.0 ! forces and moments to zero + DO I = 1,p%DOFs%NPIE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tail boom center of mass (point I) + + TmpVec1 = -p%BoomMass*RtHSdat%PLinVelEI(p%DOFs%PIE(I),0,:) ! The portion of PFrcWTail associated with the BoomMass + TmpVec2 = -p%TFinMass*RtHSdat%PLinVelEJ(p%DOFs%PIE(I),0,:) ! The portion of PFrcWTail associated with the TFinMass + TmpVec3 = CROSS_PRODUCT( RtHSdat%rWI, TmpVec1 ) ! The portion of PMomNTail associated with the BoomMass + TmpVec4 = CROSS_PRODUCT( RtHSdat%rWJ, TmpVec2 ) ! The portion of PMomNTail associated with the TFinMass + + RtHSdat%PFrcWTail(:,p%DOFs%PIE(I)) = TmpVec1 + TmpVec2 + RtHSdat%PMomNTail(:,p%DOFs%PIE(I)) = TmpVec3 + TmpVec4 - p%AtfaIner*CoordSys%tfa* & + DOT_PRODUCT( CoordSys%tfa, RtHSdat%PAngVelEA(p%DOFs%PIE(I),0,:) ) + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tail boom center of mass (point I) + +!..................................... +! FrcWTailt and MomNTailt - Forces on the tailfin +!..................................... + ! Aerodynamic loads on TailFin CM (point K), with change of coordinate system + Force(1:3) = (/ u%TFinCMLoads%Force (1,1), u%TFinCMLoads%Force (3,1), -u%TFinCMLoads%Force (2,1) /) + Moment(1:3) = (/ u%TFinCMLoads%Moment(1,1), u%TFinCMLoads%Moment(3,1), -u%TFinCMLoads%Moment(2,1) /) + + TmpVec1 = -p%BoomMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEIt ) ! The portion of FrcWTailt associated with the BoomMass + TmpVec2 = -p%TFinMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEJt ) ! The portion of FrcWTailt associated with the TFinMass + TmpVec3 = CROSS_PRODUCT( RtHSdat%rWI , TmpVec1 ) ! The portion of MomNTailt associated with the BoomMass + TmpVec4 = CROSS_PRODUCT( RtHSdat%rWJ , TmpVec2 ) ! The portion of MomNTailt associated with the TFinMass + TmpVec = p%AtfaIner*CoordSys%tfa*DOT_PRODUCT( CoordSys%tfa, RtHSdat%AngVelEA ) ! = ( A inertia dyadic ) dot ( angular velocity of the tail in the inertia frame ) + TmpVec5 = CROSS_PRODUCT( -RtHSdat%AngVelEA, TmpVec ) ! = ( -angular velocity of the tail in the inertia frame ) cross ( TmpVec ) + + RtHSdat%FrcWTailt = Force + TmpVec1 + TmpVec2 + RtHSdat%MomNTailt = Moment + TmpVec3 + TmpVec4 + TmpVec5 & + + CROSS_PRODUCT( RtHSdat%rWJ , Force ) & ! The portion of MomNTailt associated with Force with lever arm WK + - p%AtfaIner*CoordSys%tfa*DOT_PRODUCT( CoordSys%tfa, RtHSdat%AngAccEAt ) + +!..................................... +! PFrcONcRt and PMomBNcRt +! (requires PFrcVGnRt, PMomNGnRt, PFrcWTail, PMomNTail, ) +!..................................... + + ! Define the partial forces and moments (including those associated with + ! the QD2T()'s and those that are not) at the yaw bearing (point O) / + ! base plate (body B) using the nacelle, generator, rotor, and tail effects. + + RtHSdat%PFrcONcRt = RtHSdat%PFrcVGnRt + RtHSdat%PFrcWTail ! Initialize these partial forces and moments using + RtHSdat%PMomBNcRt = RtHSdat%PMomNGnRt + RtHSdat%PMomNTail ! the rotor, rotor-furl, generator, and tail effects + DO I = 1,p%DOFs%NActvDOF ! Loop through all active (enabled) DOFs + + TmpVec = CROSS_PRODUCT( RtHSdat%rOV, RtHSdat%PFrcVGnRt(:,p%DOFs%SrtPS(I)) ) ! The portion of PMomBNcRt associated with the PFrcVGnRt + + RtHSdat%PMomBNcRt(:,p%DOFs%SrtPS(I)) = RtHSdat%PMomBNcRt(:,p%DOFs%SrtPS(I)) + TmpVec + + ENDDO ! I - All active (enabled) DOFs + DO I = 1,p%DOFs%NPIE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tail boom center of mass (point I) + + TmpVec = CROSS_PRODUCT( RtHSdat%rOW, RtHSdat%PFrcWTail(:,p%DOFs%PIE(I) ) ) ! The portion of PMomBNcRt associated with the PFrcWTail + + RtHSdat%PMomBNcRt(:,p%DOFs%PIE(I) ) = RtHSdat%PMomBNcRt(:,p%DOFs%PIE(I) ) + TmpVec + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tail boom center of mass (point I) + DO I = 1,p%DOFs%NPUE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the nacelle center of mass (point U) + + TmpVec1 = -p%NacMass*RtHSdat%PLinVelEU(p%DOFs%PUE(I),0,:) ! The portion of PFrcONcRt associated with the NacMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rOU, TmpVec1 ) ! The portion of PMomBNcRt associated with the NacMass + + RtHSdat%PFrcONcRt(:,p%DOFs%PUE(I) ) = RtHSdat%PFrcONcRt(:,p%DOFs%PUE(I) ) + TmpVec1 + RtHSdat%PMomBNcRt(:,p%DOFs%PUE(I) ) = RtHSdat%PMomBNcRt(:,p%DOFs%PUE(I) ) + TmpVec2 - p%Nacd2Iner*CoordSys%d2* & + DOT_PRODUCT( CoordSys%d2, RtHSdat%PAngVelEN(p%DOFs%PUE(I),0,:) ) + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the nacelle center of mass (point U) + + +!..................................... +! FrcONcRtt and MomBNcRtt +! (requires FrcVGnRtt, MomNGnRtt, FrcWTailt, MomNTailt) +!..................................... + + TmpVec1 = -p%NacMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEUt ) ! The portion of FrcONcRtt associated with the NacMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rOU, TmpVec1 ) ! The portion of MomBNcRtt associated with the NacMass + TmpVec3 = CROSS_PRODUCT( RtHSdat%rOV, RtHSdat%FrcVGnRtt ) ! The portion of MomBNcRtt associated with the FrcVGnRtt + TmpVec4 = CROSS_PRODUCT( RtHSdat%rOW, RtHSdat%FrcWTailt ) ! The portion of MomBNcRtt associated with the FrcWTailt + TmpVec = p%Nacd2Iner*CoordSys%d2*DOT_PRODUCT( CoordSys%d2, RtHSdat%AngVelEN ) ! = ( Nacelle inertia dyadic ) dot ( angular velocity of nacelle in the inertia frame ) + + RtHSdat%FrcONcRtt = RtHSdat%FrcVGnRtt + RtHSdat%FrcWTailt + TmpVec1 + (/ u%NacelleLoads%Force(1,1), u%NacelleLoads%Force(3,1), -u%NacelleLoads%Force(2,1) /) + + RtHSdat%MomBNcRtt = RtHSdat%MomNGnRtt + RtHSdat%MomNTailt + TmpVec2 + TmpVec3 + TmpVec4 & + + CROSS_PRODUCT( -RtHSdat%AngVelEN, TmpVec ) & ! = ( -angular velocity of nacelle in the inertia frame ) cross ( TmpVec ) & + - p%Nacd2Iner*CoordSys%d2*DOT_PRODUCT( CoordSys%d2, RtHSdat%AngAccENt ) & + + (/ u%NacelleLoads%Moment(1,1), u%NacelleLoads%Moment(3,1), -u%NacelleLoads%Moment(2,1) /) + +!..................................... +! PFTHydro and PMFHydro +! (requires TwrAddedMass) +!..................................... + + ! Compute the partial hydrodynamic forces and moments per unit length + ! (including those associated with the QD2T()'s and those that are not) at the current tower element (point T) / (body F): + + ! NOTE: These forces are named PFTHydro, PMFHydro, FTHydrot, and MFHydrot. However, the names should not imply that the + ! forces are a result of hydrodynamic contributions only. These tower forces contain contributions from any external + ! load acting on the tower other than loads transmitted from aerodynamics. For example, these tower forces contain + ! contributions from foundation stiffness and damping [not floating] or mooring line restoring and damping, + ! as well as hydrostatic and hydrodynamic contributions [offshore]. + + DO J=1,p%TwrNodes + + RtHSdat%PFTHydro(:,J,:) = 0.0 + RtHSdat%PMFHydro(:,J,:) = 0.0 + DO I = 1,p%DOFs%NPTE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tower + + RtHSdat%PFTHydro(:,J,p%DOFs%PTE(I)) = & + CoordSys%z1*( - u%TwrAddedMass(DOF_Sg,DOF_Sg,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Sg,DOF_Sw,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Sg,DOF_Hv,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,2) & + - u%TwrAddedMass(DOF_Sg,DOF_R ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Sg,DOF_P ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Sg,DOF_Y ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,2) ) & + - CoordSys%z3*( - u%TwrAddedMass(DOF_Sw,DOF_Sg,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Sw,DOF_Sw,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Sw,DOF_Hv,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,2) & + - u%TwrAddedMass(DOF_Sw,DOF_R ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Sw,DOF_P ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Sw,DOF_Y ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,2) ) & + + CoordSys%z2*( - u%TwrAddedMass(DOF_Hv,DOF_Sg,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Hv,DOF_Sw,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Hv,DOF_Hv,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,2) & + - u%TwrAddedMass(DOF_Hv,DOF_R ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Hv,DOF_P ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Hv,DOF_Y ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,2) ) + RtHSdat%PMFHydro(:,J,p%DOFs%PTE(I)) = & + CoordSys%z1*( - u%TwrAddedMass(DOF_R ,DOF_Sg,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_R ,DOF_Sw,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_R ,DOF_Hv,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,2) & + - u%TwrAddedMass(DOF_R ,DOF_R ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_R ,DOF_P ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_R ,DOF_Y ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,2) ) & + - CoordSys%z3*( - u%TwrAddedMass(DOF_P ,DOF_Sg,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_P ,DOF_Sw,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_P ,DOF_Hv,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,2) & + - u%TwrAddedMass(DOF_P ,DOF_R ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_P ,DOF_P ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_P ,DOF_Y ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,2) ) & + + CoordSys%z2*( - u%TwrAddedMass(DOF_Y ,DOF_Sg,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Y ,DOF_Sw,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Y ,DOF_Hv,J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,2) & + - u%TwrAddedMass(DOF_Y ,DOF_R ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,1) & + + u%TwrAddedMass(DOF_Y ,DOF_P ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,3) & + - u%TwrAddedMass(DOF_Y ,DOF_Y ,J)*RtHSdat%PAngVelEF(J,p%DOFs%PTE(I),0,2) ) + + END DO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tower + END DO !J + +!..................................... +! FTHydrot and MFHydrot +! (requires TwrAddedMass) +!..................................... + + DO J=1,p%TwrNodes + RtHSdat%FTHydrot(:,J) = CoordSys%z1*( u%TowerPtLoads%Force(DOF_Sg,J)/abs(p%DHNodes(J)) & + - u%TwrAddedMass(DOF_Sg,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + + u%TwrAddedMass(DOF_Sg,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & + - u%TwrAddedMass(DOF_Sg,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & + - u%TwrAddedMass(DOF_Sg,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + + u%TwrAddedMass(DOF_Sg,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & + - u%TwrAddedMass(DOF_Sg,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & + - CoordSys%z3*( u%TowerPtLoads%Force(DOF_Sw,J)/abs(p%DHNodes(J)) & + - u%TwrAddedMass(DOF_Sw,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + + u%TwrAddedMass(DOF_Sw,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & + - u%TwrAddedMass(DOF_Sw,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & + - u%TwrAddedMass(DOF_Sw,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + + u%TwrAddedMass(DOF_Sw,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & + - u%TwrAddedMass(DOF_Sw,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & + + CoordSys%z2*( u%TowerPtLoads%Force(DOF_Hv,J)/abs(p%DHNodes(J)) & + - u%TwrAddedMass(DOF_Hv,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + + u%TwrAddedMass(DOF_Hv,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & + - u%TwrAddedMass(DOF_Hv,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & + - u%TwrAddedMass(DOF_Hv,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + + u%TwrAddedMass(DOF_Hv,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & + - u%TwrAddedMass(DOF_Hv,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) + RtHSdat%MFHydrot(:,J) = CoordSys%z1*( u%TowerPtLoads%Moment(DOF_R-3,J)/abs(p%DHNodes(J)) & + - u%TwrAddedMass(DOF_R ,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + + u%TwrAddedMass(DOF_R ,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & + - u%TwrAddedMass(DOF_R ,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & + - u%TwrAddedMass(DOF_R ,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + + u%TwrAddedMass(DOF_R ,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & + - u%TwrAddedMass(DOF_R ,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & + - CoordSys%z3*( u%TowerPtLoads%Moment(DOF_P-3 ,J)/abs(p%DHNodes(J)) & + - u%TwrAddedMass(DOF_P ,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + + u%TwrAddedMass(DOF_P ,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & + - u%TwrAddedMass(DOF_P ,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & + - u%TwrAddedMass(DOF_P ,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + + u%TwrAddedMass(DOF_P ,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & + - u%TwrAddedMass(DOF_P ,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) & + + CoordSys%z2*( u%TowerPtLoads%Moment(DOF_Y-3 ,J)/abs(p%DHNodes(J)) & + - u%TwrAddedMass(DOF_Y ,DOF_Sg,J)*RtHSdat%LinAccETt(1,J) & + + u%TwrAddedMass(DOF_Y ,DOF_Sw,J)*RtHSdat%LinAccETt(3,J) & + - u%TwrAddedMass(DOF_Y ,DOF_Hv,J)*RtHSdat%LinAccETt(2,J) & + - u%TwrAddedMass(DOF_Y ,DOF_R ,J)*RtHSdat%AngAccEFt(1,J) & + + u%TwrAddedMass(DOF_Y ,DOF_P ,J)*RtHSdat%AngAccEFt(3,J) & + - u%TwrAddedMass(DOF_Y ,DOF_Y ,J)*RtHSdat%AngAccEFt(2,J) ) + + END DO !J + +!..................................... +! PFrcT0Trb and PMomX0Trb +! (requires PFrcONcRt, PMomBNcRt, PFrcT0Trb, PMomX0Trb, PFTHydro, PMFHydro) +!..................................... + + ! Initialize the partial forces and moments (including those associated + ! with the QD2T()'s and those that are not) at the tower base (point T(0)) using everything but the tower: + + RtHSdat%PFrcT0Trb = RtHSdat%PFrcONcRt ! Initialize these partial forces and moments + RtHSdat%PMomX0Trb = RtHSdat%PMomBNcRt ! using all of the effects above the yaw bearing + DO I = 1,p%DOFs%NActvDOF ! Loop through all active (enabled) DOFs + + TmpVec = CROSS_PRODUCT( RtHSdat%rT0O, RtHSdat%PFrcONcRt(:,p%DOFs%SrtPS(I)) ) ! The portion of PMomX0Trb associated with the PFrcONcRt + + RtHSdat%PMomX0Trb(:,p%DOFs%SrtPS(I)) = RtHSdat%PMomX0Trb(:,p%DOFs%SrtPS(I)) + TmpVec + + ENDDO ! I - All active (enabled) DOFs + DO I = 1,p%DOFs%NPTE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the yaw bearing center of mass (point O) + + TmpVec1 = -p%YawBrMass*RtHSdat%PLinVelEO(p%DOFs%PTE(I),0,:) ! The portion of PFrcT0Trb associated with the YawBrMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0O, TmpVec1 ) ! The portion of PMomX0Trb associated with the YawBrMass + + RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I) ) = RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I) ) + TmpVec1 + RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I) ) = RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I) ) + TmpVec2 + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the yaw bearing center of mass (point O) + + TmpVec1 = -p%YawBrMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEOt ) ! The portion of FrcT0Trbt associated with the YawBrMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0O, TmpVec1 ) ! The portion of MomX0Trbt associated with the YawBrMass + TmpVec3 = CROSS_PRODUCT( RtHSdat%rT0O, RtHSdat%FrcONcRtt ) ! The portion of MomX0Trbt associated with the FrcONcRtt + + RtHSdat%FrcT0Trbt = RtHSdat%FrcONcRtt + TmpVec1 + RtHSdat%MomX0Trbt = RtHSdat%MomBNcRtt + TmpVec2 + TmpVec3 + + ! Integrate to find the total partial forces and moments (including those + ! associated with the QD2T()'s and those that are not) at the tower base (point T(0)): + DO J=1,p%TwrNodes + + DO I = 1,p%DOFs%NPTE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tower + + TmpVec1 = RtHSdat%PFTHydro(:,J,p%DOFs%PTE(I))*abs(p%DHNodes(J)) - p%TElmntMass(J)*RtHSdat%PLinVelET(J,p%DOFs%PTE(I),0,:) ! The portion of PFrcT0Trb associated with tower element J + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0T(:,J), TmpVec1 ) ! The portion of PMomX0Trb associated with tower element J + TmpVec3 = RtHSdat%PMFHydro(:,J,p%DOFs%PTE(I))*abs(p%DHNodes(J)) ! The added moment applied at tower element J + + RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I)) = RtHSdat%PFrcT0Trb(:,p%DOFs%PTE(I)) + TmpVec1 + RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I)) = RtHSdat%PMomX0Trb(:,p%DOFs%PTE(I)) + TmpVec2 + TmpVec3 + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the tower + + TmpVec1 = ( RtHSdat%FTHydrot(:,J) )*abs(p%DHNodes(J)) & + - p%TElmntMass(J)*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccETt(:,J) ) ! The portion of FrcT0Trbt associated with tower element J + TmpVec2 = CROSS_PRODUCT( RtHSdat%rT0T(:,J), TmpVec1 ) ! The portion of MomX0Trbt associated with tower element J + TmpVec3 = ( RtHSdat%MFHydrot(:,J) )*abs(p%DHNodes(J)) ! The external moment applied to tower element J + + RtHSdat%FrcT0Trbt = RtHSdat%FrcT0Trbt + TmpVec1 + + RtHSdat%MomX0Trbt = RtHSdat%MomX0Trbt + TmpVec2 + TmpVec3 + + END DO !J + +!..................................... +! PFZHydro and PMXHydro +! ( requires PtfmAddedMass ) +!..................................... + + !.................................................................................................................................. + ! Compute the partial platform forces and moments (including those associated with the QD2T()'s and those that are not) at the + ! platform reference (point Z) / (body X). + ! + ! NOTE: These forces are named PFZHydro, PMXHydro, FZHydrot, and MXHydrot. However, the names should not imply that the forces + ! are a result of hydrodynamic contributions only. These platform forces contain contributions from any external load acting + ! on the platform other than loads transmitted from the wind turbine. For example, these platform forces contain contributions + ! from foundation stiffness and damping [not floating] or mooring line restoring and damping [floating], as well as hydrostatic + ! and hydrodynamic contributions [offshore]. + !bjj: m%RtHS%PFZHydro, %PMXHydro, %FZHydrot, and %MXHydrot are not used in the output routine anymore + ! (because of their dependence on inputs, u) + + RtHSdat%PFZHydro = 0.0 + RtHSdat%PMXHydro = 0.0 + DO I = 1,p%DOFs%NPYE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the platform center of mass (point Y) + + RtHSdat%PFZHydro(p%DOFs%PYE(I),:) = - u%PtfmAddedMass(DOF_Sg,p%DOFs%PYE(I))*RtHSdat%PLinVelEZ(DOF_Sg,0,:) & + - u%PtfmAddedMass(DOF_Sw,p%DOFs%PYE(I))*RtHSdat%PLinVelEZ(DOF_Sw,0,:) & + - u%PtfmAddedMass(DOF_Hv,p%DOFs%PYE(I))*RtHSdat%PLinVelEZ(DOF_Hv,0,:) + RtHSdat%PMXHydro(p%DOFs%PYE(I),:) = - u%PtfmAddedMass(DOF_R ,p%DOFs%PYE(I))*RtHSdat%PAngVelEX(DOF_R ,0,:) & + - u%PtfmAddedMass(DOF_P ,p%DOFs%PYE(I))*RtHSdat%PAngVelEX(DOF_P ,0,:) & + - u%PtfmAddedMass(DOF_Y ,p%DOFs%PYE(I))*RtHSdat%PAngVelEX(DOF_Y ,0,:) + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the platform center of mass (point Y) + + RtHSdat%FZHydrot = u%PlatformPtMesh%Force(DOF_Sg,1)*RtHSdat%PLinVelEZ(DOF_Sg,0,:) & + + u%PlatformPtMesh%Force(DOF_Sw,1)*RtHSdat%PLinVelEZ(DOF_Sw,0,:) & + + u%PlatformPtMesh%Force(DOF_Hv,1)*RtHSdat%PLinVelEZ(DOF_Hv,0,:) + RtHSdat%MXHydrot = u%PlatformPtMesh%Moment(DOF_R-3,1)*RtHSdat%PAngVelEX(DOF_R ,0,:) & + + u%PlatformPtMesh%Moment(DOF_P-3,1)*RtHSdat%PAngVelEX(DOF_P ,0,:) & + + u%PlatformPtMesh%Moment(DOF_Y-3,1)*RtHSdat%PAngVelEX(DOF_Y ,0,:) + +!..................................... +! PFrcZAll and PMomXAll +! (requires PFrcT0Trb, PMomX0Trb, PFZHydro, PMXHydro ) +!..................................... + + ! Define the partial forces and moments (including those associated with the QD2T()'s and those that are not) at the + ! platform reference (point Z) / (body X) using the turbine and platform effects: + + RtHSdat%PFrcZAll = RtHSdat%PFrcT0Trb ! Initialize these partial forces and moments + RtHSdat%PMomXAll = RtHSdat%PMomX0Trb ! using the effects from the wind turbine + DO I = 1,p%DOFs%NActvDOF ! Loop through all active (enabled) DOFs + + TmpVec = CROSS_PRODUCT( RtHSdat%rZT0, RtHSdat%PFrcT0Trb(:,p%DOFs%SrtPS(I)) ) ! The portion of PMomXAll associated with the PFrcT0Trb + + RtHSdat%PMomXAll(:,p%DOFs%SrtPS(I)) = RtHSdat%PMomXAll(:,p%DOFs%SrtPS(I)) + TmpVec + + ENDDO ! I - All active (enabled) DOFs + DO I = 1,p%DOFs%NPYE ! Loop through all active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the platform center of mass (point Y) + + TmpVec1 = -p%PtfmMass*RtHSdat%PLinVelEY(p%DOFs%PYE(I),0,:) ! The portion of PFrcZAll associated with the PtfmMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rZY , TmpVec1 ) ! The portion of PMomXAll associated with the PtfmMass + + RtHSdat%PFrcZAll(:,p%DOFs%PYE(I)) = RtHSdat%PFrcZAll(:,p%DOFs%PYE(I) ) + RtHSdat%PFZHydro(p%DOFs%PYE(I),:) + TmpVec1 + RtHSdat%PMomXAll(:,p%DOFs%PYE(I)) = RtHSdat%PMomXAll(:,p%DOFs%PYE(I) ) + RtHSdat%PMXHydro(p%DOFs%PYE(I),:) + TmpVec2 & + - p%PtfmRIner*CoordSys%a1*DOT_PRODUCT( CoordSys%a1, RtHSdat%PAngVelEX(p%DOFs%PYE(I),0,:) ) & + - p%PtfmYIner*CoordSys%a2*DOT_PRODUCT( CoordSys%a2, RtHSdat%PAngVelEX(p%DOFs%PYE(I),0,:) ) & + - p%PtfmPIner*CoordSys%a3*DOT_PRODUCT( CoordSys%a3, RtHSdat%PAngVelEX(p%DOFs%PYE(I),0,:) ) + + ENDDO ! I - All active (enabled) DOFs that contribute to the QD2T-related linear accelerations of the platform center of mass (point Y) + +!..................................... +! FrcZAllt and MomXAllt +! (requires FrcT0Trbt, MomX0Trbt) +!..................................... + + TmpVec1 = -p%PtfmMass*( p%Gravity*CoordSys%z2 + RtHSdat%LinAccEYt ) ! The portion of FrcZAllt associated with the PtfmMass + TmpVec2 = CROSS_PRODUCT( RtHSdat%rZY , TmpVec1 ) ! The portion of MomXAllt associated with the PtfmMass + TmpVec3 = CROSS_PRODUCT( RtHSdat%rZT0 , RtHSdat%FrcT0Trbt ) ! The portion of MomXAllt associated with the FrcT0Trbt + TmpVec = p%PtfmRIner*CoordSys%a1*DOT_PRODUCT( CoordSys%a1, RtHSdat%AngVelEX ) & ! = ( Platform inertia dyadic ) dot ( angular velocity of platform in the inertia frame ) + + p%PtfmYIner*CoordSys%a2*DOT_PRODUCT( CoordSys%a2, RtHSdat%AngVelEX ) & + + p%PtfmPIner*CoordSys%a3*DOT_PRODUCT( CoordSys%a3, RtHSdat%AngVelEX ) + TmpVec4 = CROSS_PRODUCT( -RtHSdat%AngVelEX, TmpVec ) ! = ( -angular velocity of platform in the inertia frame ) cross ( TmpVec ) + + RtHSdat%FrcZAllt = RtHSdat%FrcT0Trbt + RtHSdat%FZHydrot + TmpVec1 + RtHSdat%MomXAllt = RtHSdat%MomX0Trbt + RtHSdat%MXHydrot + TmpVec2 + TmpVec3 + TmpVec4 + + +END SUBROUTINE CalculateForcesMoments +``` \ No newline at end of file diff --git a/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculatePositions.md b/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculatePositions.md new file mode 100644 index 0000000..0a550b5 --- /dev/null +++ b/书籍/力学书籍/OpenFast/FASTKinetics/auto/CalculatePositions.md @@ -0,0 +1,143 @@ + +```fortran +SUBROUTINE CalculatePositions( p, x, CoordSys, RtHSdat ) +!.................................................................................................................................. + + ! Passed variables + TYPE(ED_ParameterType), INTENT(IN ) :: p !< Parameters + TYPE(ED_ContinuousStateType), INTENT(IN ) :: x !< Continuous states at Time + TYPE(ED_CoordSys), INTENT(IN ) :: CoordSys !< The coordinate systems that have been set for these states/time + TYPE(ED_RtHndSide), INTENT(INOUT) :: RtHSdat !< data from the RtHndSid module (contains positions to be set) + + !Local variables + !REAL(R8Ki) :: rQ (3) ! Position vector from inertial frame origin to apex of rotation (point Q). + + INTEGER(IntKi) :: J ! Counter for elements + INTEGER(IntKi) :: K ! Counter for blades + + !------------------------------------------------------------------------------------------------- + ! Positions + !------------------------------------------------------------------------------------------------- + + ! Define the position vectors between the various points on the wind turbine + ! that are not dependent on the distributed tower or blade parameters: + + RtHSdat%rZ = x%QT(DOF_Sg)* CoordSys%z1 + x%QT(DOF_Hv)* CoordSys%z2 - x%QT(DOF_Sw)* CoordSys%z3 ! Position vector from inertia frame origin to platform reference (point Z). + RtHSdat%rZY = p%rZYzt* CoordSys%a2 + p%PtfmCMxt*CoordSys%a1 - p%PtfmCMyt*CoordSys%a3 ! Position vector from platform reference (point Z) to platform mass center (point Y). + RtHSdat%rZT0 = p%rZT0zt* CoordSys%a2 ! Position vector from platform reference (point Z) to tower base (point T(0)) + RtHSdat%rZO = ( x%QT(DOF_TFA1) + x%QT(DOF_TFA2) )*CoordSys%a1 & ! Position vector from platform reference (point Z) to tower-top / base plate (point O). + + ( p%RefTwrHt - 0.5*( p%AxRedTFA(1,1,p%TTopNode)*x%QT(DOF_TFA1)*x%QT(DOF_TFA1) & + + p%AxRedTFA(2,2,p%TTopNode)*x%QT(DOF_TFA2)*x%QT(DOF_TFA2) & + + 2.0*p%AxRedTFA(1,2,p%TTopNode)*x%QT(DOF_TFA1)*x%QT(DOF_TFA2) & + + p%AxRedTSS(1,1,p%TTopNode)*x%QT(DOF_TSS1)*x%QT(DOF_TSS1) & + + p%AxRedTSS(2,2,p%TTopNode)*x%QT(DOF_TSS2)*x%QT(DOF_TSS2) & + + 2.0*p%AxRedTSS(1,2,p%TTopNode)*x%QT(DOF_TSS1)*x%QT(DOF_TSS2) ) )*CoordSys%a2 & + + ( x%QT(DOF_TSS1) + x%QT(DOF_TSS2) )*CoordSys%a3 + RtHSdat%rOU = p%NacCMxn*CoordSys%d1 + p%NacCMzn *CoordSys%d2 - p%NacCMyn *CoordSys%d3 ! Position vector from tower-top / base plate (point O) to nacelle center of mass (point U). + RtHSdat%rOV = p%RFrlPnt_n(1)*CoordSys%d1 + p%RFrlPnt_n(3)*CoordSys%d2 - p%RFrlPnt_n(2)*CoordSys%d3 ! Position vector from tower-top / base plate (point O) to specified point on rotor-furl axis (point V). + RtHSdat%rVIMU = p%rVIMUxn*CoordSys%rf1 + p%rVIMUzn *CoordSys%rf2 - p%rVIMUyn *CoordSys%rf3 ! Position vector from specified point on rotor-furl axis (point V) to nacelle IMU (point IMU). + RtHSdat%rVD = p%rVDxn*CoordSys%rf1 + p%rVDzn *CoordSys%rf2 - p%rVDyn *CoordSys%rf3 ! Position vector from specified point on rotor-furl axis (point V) to center of mass of structure that furls with the rotor (not including rotor) (point D). + RtHSdat%rVP = p%rVPxn*CoordSys%rf1 + p%rVPzn *CoordSys%rf2 - p%rVPyn *CoordSys%rf3 + p%OverHang*CoordSys%c1 ! Position vector from specified point on rotor-furl axis (point V) to teeter pin (point P). + RtHSdat%rPQ = -p%UndSling*CoordSys%g1 ! Position vector from teeter pin (point P) to apex of rotation (point Q). + RtHSdat%rQC = p%HubCM*CoordSys%g1 ! Position vector from apex of rotation (point Q) to hub center of mass (point C). + RtHSdat%rOW = p%TFrlPnt_n(1)*CoordSys%d1 + p%TFrlPnt_n(3) *CoordSys%d2 - p%TFrlPnt_n(2)*CoordSys%d3 ! Position vector from tower-top / base plate (point O) to specified point on tail-furl axis (point W). + RtHSdat%rWI = p%rWIxn*CoordSys%tf1 + p%rWIzn*CoordSys%tf2 - p%rWIyn*CoordSys%tf3 ! Position vector from specified point on tail-furl axis (point W) to tail boom center of mass (point I). + RtHSdat%rWJ = p%rWJxn*CoordSys%tf1 + p%rWJzn*CoordSys%tf2 - p%rWJyn*CoordSys%tf3 ! Position vector from specified point on tail-furl axis (point W) to tail fin center of mass (point J). + RtHSdat%rPC = RtHSdat%rPQ + RtHSdat%rQC ! Position vector from teeter pin (point P) to hub center of mass (point C). + RtHSdat%rT0O = RtHSdat%rZO - RtHSdat%rZT0 ! Position vector from the tower base (point T(0)) to tower-top / base plate (point O). + RtHSdat%rO = RtHSdat%rZ + RtHSdat%rZO ! Position vector from inertial frame origin to tower-top / base plate (point O). + RtHSdat%rV = RtHSdat%rO + RtHSdat%rOV ! Position vector from inertial frame origin to specified point on rotor-furl axis (point V) + !RtHSdat%rP = RtHSdat%rO + RtHSdat%rOV + RtHSdat%rVP ! Position vector from inertial frame origin to teeter pin (point P). + RtHSdat%rP = RtHSdat%rV + RtHSdat%rVP ! Position vector from inertial frame origin to teeter pin (point P). + RtHSdat%rQ = RtHSdat%rP + RtHSdat%rPQ ! Position vector from inertial frame origin to apex of rotation (point Q). + RtHSdat%rJ = RtHSdat%rO + RtHSdat%rOW + RtHSdat%rWJ ! Position vector from inertial frame origin to tail fin center of mass (point J). + + + DO K = 1,p%NumBl ! Loop through all blades + + ! Calculate the position vector of the tip: + RtHSdat%rS0S(:,K,p%TipNode) = ( p%TwistedSF(K,1,1,p%TipNode,0)*x%QT( DOF_BF(K,1) ) & ! Position vector from the blade root (point S(0)) to the blade tip (point S(p%BldFlexL)). + + 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,:) + RtHSdat%rQS (:,K,p%TipNode) = RtHSdat%rS0S(:,K,p%TipNode) + p%HubRad*CoordSys%j3(K,:) ! Position vector from apex of rotation (point Q) to the blade tip (point S(p%BldFlexL)). + RtHSdat%rS (:,K,p%TipNode) = RtHSdat%rQS (:,K,p%TipNode) + RtHSdat%rQ ! Position vector from inertial frame origin to the blade tip (point S(p%BldFlexL)). + + ! position vectors for blade root node: + RtHSdat%rQS (:,K,0) = p%HubRad*CoordSys%j3(K,:) + RtHSdat%rS (:,K,0) = p%HubRad*CoordSys%j3(K,:) + RtHSdat%rQ + + + ! Calculate the position vector from the teeter pin to the blade root: + + RtHSdat%rPS0(:,K) = RtHSdat%rPQ + p%HubRad*CoordSys%j3(K,:) ! Position vector from teeter pin (point P) to blade root (point S(0)). + + + DO J = 1,p%BldNodes ! Loop through the blade nodes / elements + + + ! Calculate the position vector of the current node: + + RtHSdat%rS0S(:,K,J) = ( p%TwistedSF(K,1,1,J,0)*x%QT( DOF_BF(K,1) ) & ! Position vector from the blade root (point S(0)) to the current node (point S(RNodes(J)). + + p%TwistedSF(K,1,2,J,0)*x%QT( DOF_BF(K,2) ) & + + p%TwistedSF(K,1,3,J,0)*x%QT( DOF_BE(K,1) ) )*CoordSys%j1(K,:) & + + ( p%TwistedSF(K,2,1,J,0)*x%QT( DOF_BF(K,1) ) & + + p%TwistedSF(K,2,2,J,0)*x%QT( DOF_BF(K,2) ) & + + p%TwistedSF(K,2,3,J,0)*x%QT( DOF_BE(K,1) ) )*CoordSys%j2(K,:) & + + ( p%RNodes(J) - 0.5* & + ( p%AxRedBld(K,1,1,J)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BF(K,1) ) & + + p%AxRedBld(K,2,2,J)*x%QT( DOF_BF(K,2) )*x%QT( DOF_BF(K,2) ) & + + p%AxRedBld(K,3,3,J)*x%QT( DOF_BE(K,1) )*x%QT( DOF_BE(K,1) ) & + + 2.0*p%AxRedBld(K,1,2,J)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BF(K,2) ) & + + 2.0*p%AxRedBld(K,2,3,J)*x%QT( DOF_BF(K,2) )*x%QT( DOF_BE(K,1) ) & + + 2.0*p%AxRedBld(K,1,3,J)*x%QT( DOF_BF(K,1) )*x%QT( DOF_BE(K,1) ) ) )*CoordSys%j3(K,:) + RtHSdat%rQS (:,K,J) = RtHSdat%rS0S(:,K,J) + p%HubRad*CoordSys%j3(K,:) ! Position vector from apex of rotation (point Q) to the current node (point S(RNodes(J)). + RtHSdat%rS (:,K,J) = RtHSdat%rQS (:,K,J) + RtHSdat%rQ ! Position vector from inertial frame origin to the current node (point S(RNodes(J)). + + + END DO !J = 1,p%BldNodes ! Loop through the blade nodes / elements + + + + END DO !K = 1,p%NumBl + + + + + !---------------------------------------------------------------------------------------------------- + ! Get the tower element positions + !---------------------------------------------------------------------------------------------------- + RtHSdat%rZT (:,0) = RtHSdat%rZT0 + DO J = 1,p%TwrNodes ! Loop through the tower nodes / elements + + + ! Calculate the position vector of the current node: + + RtHSdat%rT0T(:,J) = ( p%TwrFASF(1,J,0)*x%QT(DOF_TFA1) + p%TwrFASF(2,J,0)*x%QT(DOF_TFA2) )*CoordSys%a1 & ! Position vector from base of flexible portion of tower (point T(0)) to current node (point T(J)). + + ( p%HNodes(J) - 0.5*( p%AxRedTFA(1,1,J)*x%QT(DOF_TFA1)*x%QT(DOF_TFA1) & + + p%AxRedTFA(2,2,J)*x%QT(DOF_TFA2)*x%QT(DOF_TFA2) & + + 2.0*p%AxRedTFA(1,2,J)*x%QT(DOF_TFA1)*x%QT(DOF_TFA2) & + + p%AxRedTSS(1,1,J)*x%QT(DOF_TSS1)*x%QT(DOF_TSS1) & + + p%AxRedTSS(2,2,J)*x%QT(DOF_TSS2)*x%QT(DOF_TSS2) & + + 2.0*p%AxRedTSS(1,2,J)*x%QT(DOF_TSS1)*x%QT(DOF_TSS2) ) )*CoordSys%a2 & + + ( p%TwrSSSF(1,J,0)*x%QT(DOF_TSS1) + p%TwrSSSF(2,J,0)*x%QT(DOF_TSS2) )*CoordSys%a3 + RtHSdat%rZT (:,J) = RtHSdat%rZT0 + RtHSdat%rT0T(:,J) ! Position vector from platform reference (point Z) to the current node (point T(HNodes(J)). + + + RtHSdat%rT(:,J) = RtHSdat%rZ + RtHSdat%rZT (:,J) ! Position vector from inertial frame origin to the current node (point T(HNodes(J)). + + END DO + + +END SUBROUTINE CalculatePositions + +``` \ No newline at end of file diff --git a/书籍/力学书籍/OpenFast/FASTKinetics/auto/Coeff.md b/书籍/力学书籍/OpenFast/FASTKinetics/auto/Coeff.md new file mode 100644 index 0000000..e1e595a --- /dev/null +++ b/书籍/力学书籍/OpenFast/FASTKinetics/auto/Coeff.md @@ -0,0 +1,678 @@ + +```fortran +SUBROUTINE Coeff(p,InputFileData, ErrStat, ErrMsg) +!.................................................................................................................................. + + ! Passed variables + + TYPE(ED_ParameterType), INTENT(INOUT) :: p !< Parameters of the structural dynamics module + TYPE(ED_InputFile), INTENT(IN) :: InputFileData !< all the data in the ElastoDyn input file + INTEGER(IntKi), INTENT(OUT) :: ErrStat !< Error status + CHARACTER(*), INTENT(OUT) :: ErrMsg !< Error message when ErrStat =/ ErrID_None + + + ! Local variables. + + REAL(ReKi) :: AxRdBld (3,3) ! Temporary result holding the current addition to the p%AxRedBld() array. + REAL(ReKi) :: AxRdBldOld(3,3) ! Previous AxRdBld (i.e., AxRdBld from the previous node) + REAL(ReKi) :: AxRdTFA (2,2) ! Temporary result holding the current addition to the AxRedTFA() array. + REAL(ReKi) :: AxRdTFAOld(2,2) ! Previous AxRdTFA (i.e., AxRdTFA from the previous node) + REAL(ReKi) :: AxRdTSS (2,2) ! Temporary result holding the current addition to the AxRedTSS() array. + REAL(ReKi) :: AxRdTSSOld(2,2) ! Previous AxRdTSS (i.e., AxRdTSS from the previous node) + REAL(ReKi) :: TmpDist ! Temporary distance used in the calculation of the aero center locations. + REAL(ReKi) :: TmpDistj1 ! Temporary distance used in the calculation of the aero center locations. + REAL(ReKi) :: TmpDistj2 ! Temporary distance used in the calculation of the aero center locations. + REAL(ReKi) :: ElmntStff ! (Temporary) stiffness of an element. + REAL(ReKi) :: ElStffFA ! (Temporary) tower fore-aft stiffness of an element + REAL(ReKi) :: ElStffSS ! (Temporary) tower side-to-side stiffness of an element + REAL(ReKi) :: FMomAbvNd (p%NumBl,p%BldNodes) ! FMomAbvNd(K,J) = portion of the first moment of blade K about the rotor centerline (not root, like FirstMom(K)) associated with everything above node J (including tip brake masses). + REAL(ReKi) :: KBECent (p%NumBl,1,1) ! Centrifugal-term of generalized edgewise stiffness of the blades. + REAL(ReKi) :: KBFCent (p%NumBl,2,2) ! Centrifugal-term of generalized flapwise stiffness of the blades. + REAL(ReKi) :: KTFAGrav (2,2) ! Gravitational-term of generalized fore-aft stiffness of the tower. + REAL(ReKi) :: KTSSGrav (2,2) ! Gravitational-term of generalized side-to-side stiffness of the tower. + REAL(ReKi) :: MBE (p%NumBl,1,1) ! Generalized edgewise mass of the blades. + REAL(ReKi) :: MBF (p%NumBl,2,2) ! Generalized flapwise mass of the blades. + REAL(ReKi) :: MTFA (2,2) ! Generalized fore-aft mass of the tower. + REAL(ReKi) :: MTSS (2,2) ! Generalized side-to-side mass of the tower. + REAL(ReKi) :: Shape ! Temporary result holding a value from the SHP function + REAL(ReKi) :: Shape1 ! Temporary result holding a value from the SHP function + REAL(ReKi) :: Shape2 ! Temporary result holding a value from the SHP function + REAL(ReKi) :: TMssAbvNd (p%TwrNodes) ! Portion of the tower mass associated with everything above node J (including tower-top effects) + REAL(ReKi) :: TwstdSF (2,3,0:1) ! Temperory result holding the current addition to the TwistedSF() array. + REAL(ReKi) :: TwstdSFOld(2,3,0:1) ! Previous TwstdSF (i.e., TwstdSF from the previous node) + + INTEGER(IntKi) :: I ! Generic index. + INTEGER(IntKi) :: J ! Loops through nodes / elements. + INTEGER(IntKi) :: K ! Loops through blades. + INTEGER(IntKi) :: L ! Generic index + + + ErrStat = ErrID_None + ErrMsg = '' + + !............................................................................................................................... + ! Calculate the distances from point S on a blade to the aerodynamic center in the j1 and j2 directions: + !............................................................................................................................... + + 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 ! J - Blade nodes / elements + + ENDDO ! K - Blades + + + !............................................................................................................................... + ! Calculate the structure that furls with the rotor inertia term: + !............................................................................................................................... + + p%RrfaIner = InputFileData%RFrlIner - p%RFrlMass*( (p%rVDxn**2 )*( 1.0 - p%CRFrlSkw2*p%CRFrlTlt2 ) & + + (p%rVDzn**2 )* p%CRFrlTlt2 & + + (p%rVDyn**2 )*( 1.0 - p%SRFrlSkw2*p%CRFrlTlt2 ) & + - 2.0*p%rVDxn*p%rVDzn* p%CRFrlSkew*p%CSRFrlTlt & + - 2.0*p%rVDxn*p%rVDyn* p%CSRFrlSkw*p%CRFrlTlt2 & + - 2.0*p%rVDzn*p%rVDyn* p%SRFrlSkew*p%CSRFrlTlt ) + IF ( p%RrfaIner < 0.0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' RFrlIner must not be less than RFrlMass*( perpendicular distance between rotor-furl'// & + ' axis and CM of the structure that furls with the rotor [not including rotor] )^2.' + RETURN + END IF + + !............................................................................................................................... + ! Calculate the tail boom inertia term: + !............................................................................................................................... + + p%AtfaIner = p%TFrlIner - p%BoomMass*( p%rWIxn*p%rWIxn*( 1.0 - p%CTFrlSkw2*p%CTFrlTlt2 ) & + + p%rWIzn*p%rWIzn* p%CTFrlTlt2 & + + p%rWIyn*p%rWIyn*( 1.0 - p%STFrlSkw2*p%CTFrlTlt2 ) & + - 2.0*p%rWIxn*p%rWIzn* p%CTFrlSkew*p%CSTFrlTlt & + - 2.0*p%rWIxn*p%rWIyn* p%CSTFrlSkw*p%CTFrlTlt2 & + - 2.0*p%rWIzn*p%rWIyn* p%STFrlSkew*p%CSTFrlTlt ) + IF ( p%AtfaIner < 0.0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' TFrlIner must not be less than BoomMass*( perpendicular distance between tail-furl'// & + ' axis and tail boom CM )^2.' + RETURN + ENDIF + + !............................................................................................................................... + ! Calculate the nacelle inertia terms: + !............................................................................................................................... + + p%Nacd2Iner = InputFileData%NacYIner - p%NacMass*( p%NacCMxn**2 + p%NacCMyn**2 ) ! Nacelle inertia about the d2-axis + IF ( p%Nacd2Iner < 0.0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' NacYIner must not be less than NacMass*( NacCMxn^2 + NacCMyn^2 ).' + RETURN + END IF + + ! Calculate hub inertia about its centerline passing through its c.g.. + ! This calculation assumes that the hub for a 2-blader is essentially + ! a uniform cylinder whose centerline is transverse through the cylinder + ! passing through its c.g.. That is, for a 2-blader, Hubg1Iner = + ! Hubg2Iner is the inertia of the hub about both the g1- and g2- axes. For + ! 3-bladers, Hubg1Iner is simply equal to HubIner and Hubg2Iner is zero. + ! Also, Initialize RotMass and RotIner to associated hub properties: + + IF ( p%NumBl == 2 ) THEN ! 2-blader + p%Hubg1Iner = ( InputFileData%HubIner - p%HubMass*( ( p%UndSling - p%HubCM )**2 ) )/( p%CosDel3**2 ) + p%Hubg2Iner = p%Hubg1Iner + IF ( p%Hubg1Iner < 0.0 ) THEN + ErrStat = ErrID_Fatal + ErrMsg = ' HubIner must not be less than HubMass*( UndSling - HubCM )^2 for 2-blader.' + RETURN + END IF + ELSE ! 3-blader + p%Hubg1Iner = InputFileData%HubIner + p%Hubg2Iner = 0.0 + ENDIF + + p%RotMass = p%HubMass + p%RotIner = p%Hubg1Iner + + + !............................................................................................................................... + + ! Initialize several variables to 0.0: + + p%KBF = 0.0 + p%KBE = 0.0 + KBFCent = 0.0 + KBECent = 0.0 + + p%TwrMass = 0.0 + p%KTFA = 0.0 + p%KTSS = 0.0 + KTFAGrav = 0.0 + KTSSGrav = 0.0 + + + + DO K = 1,p%NumBl ! Loop through the blades + + + ! Initialize BldMass(), FirstMom(), and SecondMom() using TipMass() effects: + + p%BldMass (K) = p%TipMass(K) + p%FirstMom (K) = p%TipMass(K)*p%BldFlexL + p%SecondMom(K) = p%TipMass(K)*p%BldFlexL*p%BldFlexL + + + DO J = p%BldNodes,1,-1 ! Loop through the blade nodes / elements in reverse + + + ! Calculate the mass of the current element + + p%BElmntMass(J,K) = p%MassB(K,J)*p%DRNodes(J) ! Mass of blade element J + + + ! Integrate to find some blade properties which will be output in .fsm + + 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) + + + ! Integrate to find FMomAbvNd: + + FMomAbvNd (K,J) = ( 0.5*p%BElmntMass(J,K) )*( p%HubRad + p%RNodes(J ) + 0.5*p%DRNodes(J ) ) + + IF ( J == p%BldNodes ) THEN ! Outermost blade element + ! Add the TipMass() effects: + + FMomAbvNd(K,J) = FmomAbvNd(K,J) + p%TipMass(K)*p%TipRad + ELSE ! All other blade elements + ! Add to FMomAbvNd(K,J) the effects from the (not yet used) portion of element J+1 + + FMomAbvNd(K,J) = FMomAbvNd(K,J) + FMomAbvNd(K,J+1) & + + ( 0.5*p%BElmntMass(J+1,K) )*( p%HubRad + p%RNodes(J+1) - 0.5*p%DRNodes(J+1) ) + ENDIF + + + ENDDO ! J - Blade nodes / elements in reverse + + IF (.NOT. p%BD4Blades) THEN + ! Calculate BldCG() using FirstMom() and BldMass(); and calculate + ! RotMass and RotIner: + + p%BldCG (K) = p%FirstMom (K) / p%BldMass (K) + p%RotMass = p%RotMass + p%BldMass (K) + p%RotIner = p%RotIner + ( p%SecondMom(K) + p%BldMass (K)*p%HubRad*( 2.0*p%BldCG(K) + p%HubRad ) )*( p%CosPreC(K)**2 ) + END IF + + ENDDO ! K - Blades + + + + DO K = 1,p%NumBl ! Loop through the blades + + + ! Initialize the generalized blade masses using tip mass effects: + + MBF(K,1,1) = p%TipMass(K) + MBF(K,2,2) = p%TipMass(K) + MBE(K,1,1) = p%TipMass(K) + + + DO J = 1,p%BldNodes ! Loop through the blade nodes / elements + + + ! Integrate to find the generalized mass of the blade (including tip mass effects). + ! Ignore the cross-correlation terms of MBF (i.e. MBF(i,j) where i /= j) since + ! these terms will never be used. + + 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 + + + ! Integrate to find the generalized stiffness of the blade (not including centrifugal + ! effects). + + ElmntStff = p%StiffBF(K,J)*p%DRNodes(J) ! Flapwise stiffness of blade element 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 = p%StiffBE(K,J)*p%DRNodes(J) ! Edgewise stiffness of blade element J + Shape = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldEdgSh(:,K), 2, ErrStat, ErrMsg ) + p%KBE (K,1,1) = p%KBE (K,1,1) + ElmntStff*Shape *Shape + + + ! Integrate to find the centrifugal-term of the generalized flapwise and edgewise + ! stiffness of the blades. Ignore the cross-correlation terms of KBFCent (i.e. + ! KBFCent(i,j) where i /= j) since these terms will never be used. + + ElmntStff = FMomAbvNd(K,J)*p%DRNodes(J)*p%RotSpeed**2 ! Centrifugal stiffness of blade element J + + Shape1 = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl1Sh(:,K), 1, ErrStat, ErrMsg ) + Shape2 = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl2Sh(:,K), 1, ErrStat, ErrMsg ) + KBFCent(K,1,1) = KBFCent(K,1,1) + ElmntStff*Shape1*Shape1 + KBFCent(K,2,2) = KBFCent(K,2,2) + ElmntStff*Shape2*Shape2 + + Shape = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldEdgSh(:,K), 1, ErrStat, ErrMsg ) + KBECent(K,1,1) = KBECent(K,1,1) + ElmntStff*Shape *Shape + + + ! 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) ! 2nd deriv. of Phi1(J) for blade K + p%TwistedSF(K,2,1,J,2) = -Shape*p%SThetaS(K,J) ! 2nd deriv. of Psi1(J) for blade K + + Shape = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl2Sh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,2,J,2) = Shape*p%CThetaS(K,J) ! 2nd deriv. of Phi2(J) for blade K + p%TwistedSF(K,2,2,J,2) = -Shape*p%SThetaS(K,J) ! 2nd deriv. of Psi2(J) for blade K + + Shape = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldEdgSh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,3,J,2) = Shape*p%SThetaS(K,J) ! 2nd deriv. of Phi3(J) for blade K + p%TwistedSF(K,2,3,J,2) = Shape*p%CThetaS(K,J) ! 2nd deriv. of Psi3(J) for blade K + + + ! Integrate to find the 1st derivatives of the twisted shape functions: + + DO I = 1,2 ! Loop through Phi and Psi + DO L = 1,3 ! Loop through all blade DOFs + 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) + ENDDO ! L - All blade DOFs + ENDDO ! I - Phi and Psi + + IF ( J /= 1 ) THEN ! All but the innermost blade element + ! Add the effects from the (not yet used) portion of element J-1 + + DO I = 1,2 ! Loop through Phi and Psi + DO L = 1,3 ! Loop through all blade DOFs + p%TwistedSF(K,I,L,J,1) = p%TwistedSF(K,I,L,J,1) + p%TwistedSF(K,I,L,J-1,1) & + + TwstdSFOld( I,L, 1) + ENDDO ! L - All blade DOFs + ENDDO ! I - Phi and Psi + ENDIF + + + ! Integrate to find the twisted shape functions themselves (i.e., their zeroeth derivative): + + DO I = 1,2 ! Loop through Phi and Psi + DO L = 1,3 ! Loop through all blade DOFs + 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) + ENDDO ! L - All blade DOFs + ENDDO ! I - Phi and Psi + + IF ( J /= 1 ) THEN ! All but the innermost blade element + ! Add the effects from the (not yet used) portion of element J-1 + + DO I = 1,2 ! Loop through Phi and Psi + DO L = 1,3 ! Loop through all blade DOFs + p%TwistedSF(K,I,L,J,0) = p%TwistedSF(K,I,L,J,0) + p%TwistedSF(K,I,L,J-1,0) & + + TwstdSFOld( I,L, 0) + ENDDO ! L - All blade DOFs + ENDDO ! I - Phi and Psi + ENDIF + + + ! Integrate to find the blade axial reduction shape functions: + + DO I = 1,3 ! Loop through all blade DOFs + DO L = 1,3 ! Loop through all blade DOFs + AxRdBld ( I,L ) = 0.5*p%DRNodes(J)*( & + p%TwistedSF(K,1,I,J,1)*p%TwistedSF(K,1,L,J,1) & + + p%TwistedSF(K,2,I,J,1)*p%TwistedSF(K,2,L,J,1) ) + p%AxRedBld (K,I,L,J) = AxRdBld(I,L) + ENDDO ! L - All blade DOFs + ENDDO ! I - All blade DOFs + + IF ( J /= 1 ) THEN ! All but the innermost blade element + ! Add the effects from the (not yet used) portion of element J-1 + + DO I = 1,3 ! Loop through all blade DOFs + DO L = 1,3 ! Loop through all blade DOFs + p%AxRedBld(K,I,L,J) = p%AxRedBld(K,I,L,J) + p%AxRedBld(K,I,L,J-1) & + + AxRdBldOld(I,L) + ENDDO ! L - All blade DOFs + ENDDO ! I - All blade DOFs + ENDIF + + + ! Store the TwstdSF and AxRdBld terms of the current element (these will be used for the next element) + + TwstdSFOld = TwstdSF + AxRdBldOld = AxRdBld + + + ENDDO ! J - Blade nodes / elements + + + + + IF (p%BD4Blades) THEN + + !p%KBF ( K,:,: ) = 0.0_ReKi + + ! the 1st and zeroeth derivatives of the twisted shape functions at the blade root: + p%TwistedSF(K,:,:,:,1) = 0.0_ReKi + p%TwistedSF(K,:,:,:,0) = 0.0_ReKi + p%AxRedBld( K,:,:,: ) = 0.0_ReKi + ELSE + + ! Apply the flapwise modal stiffness tuners of the blades to KBF(): + + DO I = 1,2 ! Loop through flap DOFs + DO L = 1,2 ! Loop through flap DOFs + p%KBF(K,I,L) = SQRT( p%FStTunr(K,I)*p%FStTunr(K,L) )*p%KBF(K,I,L) + ENDDO ! L - Flap DOFs + ENDDO ! I - Flap DOFs + + ! Calculate the blade natural frequencies: + + DO I = 1,NumBF ! Loop through flap DOFs + p%FreqBF(K,I,1) = Inv2Pi*SQRT( p%KBF(K,I,I) /( MBF(K,I,I) - p%TipMass(K) ) ) ! Natural blade I-flap frequency w/o centrifugal stiffening nor tip mass effects + p%FreqBF(K,I,2) = Inv2Pi*SQRT( p%KBF(K,I,I) / MBF(K,I,I) ) ! Natural blade I-flap frequency w/o centrifugal stiffening, but w/ tip mass effects + p%FreqBF(K,I,3) = Inv2Pi*SQRT( ( p%KBF(K,I,I) + KBFCent(K,I,I) )/ MBF(K,I,I) ) ! Natural blade I-flap frequency w/ centrifugal stiffening and tip mass effects + ENDDO ! I - Flap DOFs + + p%FreqBE (K,1,1) = Inv2Pi*SQRT( p%KBE(K,1,1) /( MBE(K,1,1) - p%TipMass(K) ) ) ! Natural blade 1-edge frequency w/o centrifugal stiffening nor tip mass effects + p%FreqBE (K,1,2) = Inv2Pi*SQRT( p%KBE(K,1,1) / MBE(K,1,1) ) ! Natural Blade 1-edge frequency w/o centrifugal stiffening, but w/ tip mass effects + p%FreqBE (K,1,3) = Inv2Pi*SQRT( ( p%KBE(K,1,1) + KBECent(K,1,1) )/ MBE(K,1,1) ) ! Natural Blade 1-edge frequency w/ centrifugal stiffening and tip mass effects + + + ! Calculate the generalized damping of the blades: + + DO I = 1,NumBF ! Loop through flap DOFs + DO L = 1,NumBF ! Loop through flap DOFs + p%CBF(K,I,L) = ( 0.01*p%BldFDamp(K,L) )*p%KBF(K,I,L)/( Pi*p%FreqBF(K,L,1) ) + ENDDO ! L - Flap DOFs + ENDDO ! I - Flap DOFs + + p%CBE (K,1,1) = ( 0.01*p%BldEDamp(K,1) )*p%KBE(K,1,1)/( Pi*p%FreqBE(K,1,1) ) + + + ! Calculate the 2nd derivatives of the twisted shape functions at the blade root: + + Shape = SHP( 0.0_ReKi, p%BldFlexL, p%BldFl1Sh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,1,0,2) = Shape*p%CThetaS(K,0) ! 2nd deriv. of Phi1(0) for blade K + p%TwistedSF(K,2,1,0,2) = -Shape*p%SThetaS(K,0) ! 2nd deriv. of Psi1(0) for blade K + + Shape = SHP( 0.0_ReKi, p%BldFlexL, p%BldFl2Sh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,2,0,2) = Shape*p%CThetaS(K,0) ! 2nd deriv. of Phi2(0) for blade K + p%TwistedSF(K,2,2,0,2) = -Shape*p%SThetaS(K,0) ! 2nd deriv. of Psi2(0) for blade K + + Shape = SHP( 0.0_ReKi, p%BldFlexL, p%BldEdgSh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,3,0,2) = Shape*p%SThetaS(K,0) ! 2nd deriv. of Phi3(0) for blade K + p%TwistedSF(K,2,3,0,2) = Shape*p%CThetaS(K,0) ! 2nd deriv. of Psi3(0) for blade K + + + ! Calculate the 2nd derivatives of the twisted shape functions at the tip: + + Shape = SHP( 1.0_ReKi, p%BldFlexL, p%BldFl1Sh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,1,p%TipNode,2) = Shape*p%CThetaS(K,p%TipNode) ! 2nd deriv. of Phi1(p%TipNode) for blade K + p%TwistedSF(K,2,1,p%TipNode,2) = -Shape*p%SThetaS(K,p%TipNode) ! 2nd deriv. of Psi1(p%TipNode) for blade K + + Shape = SHP( 1.0_ReKi, p%BldFlexL, p%BldFl2Sh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,2,p%TipNode,2) = Shape*p%CThetaS(K,p%TipNode) ! 2nd deriv. of Phi2(p%TipNode) for blade K + p%TwistedSF(K,2,2,p%TipNode,2) = -Shape*p%SThetaS(K,p%TipNode) ! 2nd deriv. of Psi2(p%TipNode) for blade K + + Shape = SHP( 1.0_ReKi, p%BldFlexL, p%BldEdgSh(:,K), 2, ErrStat, ErrMsg ) + p%TwistedSF(K,1,3,p%TipNode,2) = Shape*p%SThetaS(K,p%TipNode) ! 2nd deriv. of Phi3(p%TipNode) for blade K + p%TwistedSF(K,2,3,p%TipNode,2) = Shape*p%CThetaS(K,p%TipNode) ! 2nd deriv. of Psi3(p%TipNode) for blade K + + + ! Integrate to find the 1st and zeroeth derivatives of the twisted shape functions + ! at the tip: + + DO I = 1,2 ! Loop through Phi and Psi + DO L = 1,3 ! Loop through all blade DOFs + p%TwistedSF(K,I,L,p%TipNode,1) = p%TwistedSF(K,I,L,p%BldNodes,1) + TwstdSFOld(I,L,1) + p%TwistedSF(K,I,L,p%TipNode,0) = p%TwistedSF(K,I,L,p%BldNodes,0) + TwstdSFOld(I,L,0) + ENDDO ! L - All blade DOFs + ENDDO ! I - Phi and Psi + + ! the 1st and zeroeth derivatives of the twisted shape functions at the blade root: + p%TwistedSF(K,:,:,0,1) = 0.0_ReKi + p%TwistedSF(K,:,:,0,0) = 0.0_ReKi + p%AxRedBld( K,:,:,0 ) = 0.0_ReKi + + ! Integrate to find the blade axial reduction shape functions at the tip: + + DO I = 1,3 ! Loop through all blade DOFs + DO L = 1,3 ! Loop through all blade DOFs + p%AxRedBld(K,I,L,p%TipNode) = p%AxRedBld(K,I,L,p%BldNodes) + AxRdBldOld(I,L) + ENDDO ! L - All blade DOFs + ENDDO ! I - All blade DOFs + END IF ! p%BD4Blades + + + ENDDO ! K - Blades + + + + ! Calculate the tower-top mass: + + p%TwrTpMass = p%RotMass + p%RFrlMass + p%BoomMass + p%TFinMass + p%NacMass + p%YawBrMass + + + DO J = p%TwrNodes,1,-1 ! Loop through the tower nodes / elements in reverse + + + ! Calculate the mass of the current element + + p%TElmntMass(J) = p%MassT(J)*abs(p%DHNodes(J)) ! Mass of tower element J + + + ! Integrate to find the tower mass which will be output in .fsm + + p%TwrMass = p%TwrMass + p%TElmntMass(J) + + + ! Integrate to find TMssAbvNd: + + TMssAbvNd (J) = 0.5*p%TElmntMass(J) + + IF ( J == p%TwrNodes ) THEN ! Uppermost tower element + ! Add the TwrTpMass effects: + + TMssAbvNd(J) = TMssAbvNd(J) + p%TwrTpMass + ELSE ! All other tower elements + ! Add to TMssAbvNd(J) the effects from the (not yet used) portion of element J+1 + + TMssAbvNd(J) = 0.5*p%TElmntMass(J+1) + TMssAbvNd(J) + TMssAbvNd(J+1) + ENDIF + + + ENDDO ! J - Tower nodes / elements in reverse + + + + ! Initialize the generalized tower masses using tower-top mass effects: + + DO I = 1,2 ! Loop through all tower modes in a single direction + MTFA(I,I) = p%TwrTpMass + MTSS(I,I) = p%TwrTpMass + ENDDO ! I - All tower modes in a single direction + + ! set values for tower base (note that we haven't corrctly defined the values for (:,0,2) in the arrays below): + p%TwrFASF( :,0,0:1) = 0.0_ReKi + p%TwrSSSF( :,0,0:1) = 0.0_ReKi + p%AxRedTFA(:,:,0) = 0.0_ReKi + p%AxRedTSS(:,:,0) = 0.0_ReKi + + DO J = 1,p%TwrNodes ! Loop through the tower nodes / elements + + + ! Calculate the tower shape functions (all derivatives): + + p%TwrFASF(1,J,2) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM1Sh(:), 2, ErrStat, ErrMsg ) + p%TwrFASF(2,J,2) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM2Sh(:), 2, ErrStat, ErrMsg ) + p%TwrFASF(1,J,1) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM1Sh(:), 1, ErrStat, ErrMsg ) + p%TwrFASF(2,J,1) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM2Sh(:), 1, ErrStat, ErrMsg ) + p%TwrFASF(1,J,0) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM1Sh(:), 0, ErrStat, ErrMsg ) + p%TwrFASF(2,J,0) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwFAM2Sh(:), 0, ErrStat, ErrMsg ) + + p%TwrSSSF(1,J,2) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwSSM1Sh(:), 2, ErrStat, ErrMsg ) + p%TwrSSSF(2,J,2) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwSSM2Sh(:), 2, ErrStat, ErrMsg ) + p%TwrSSSF(1,J,1) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwSSM1Sh(:), 1, ErrStat, ErrMsg ) + p%TwrSSSF(2,J,1) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwSSM2Sh(:), 1, ErrStat, ErrMsg ) + p%TwrSSSF(1,J,0) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwSSM1Sh(:), 0, ErrStat, ErrMsg ) + p%TwrSSSF(2,J,0) = SHP( p%HNodesNorm(J), p%TwrFlexL, InputFileData%TwSSM2Sh(:), 0, ErrStat, ErrMsg ) + + + ! Integrate to find the generalized mass of the tower (including tower-top mass effects). + ! Ignore the cross-correlation terms of MTFA (i.e. MTFA(i,j) where i /= j) and MTSS + ! since these terms will never be used. + + + DO I = 1,2 ! Loop through all tower DOFs in one direction + MTFA (I,I) = MTFA (I,I) + p%TElmntMass(J)*p%TwrFASF(I,J,0)**2 + MTSS (I,I) = MTSS (I,I) + p%TElmntMass(J)*p%TwrSSSF(I,J,0)**2 + ENDDO ! I - through all tower DOFs in one direction + + + ! Integrate to find the generalized stiffness of the tower (not including gravitational + ! effects). + + ElStffFA = p%StiffTFA(J)*abs(p%DHNodes(J)) ! Fore-aft stiffness of tower element J + ElStffSS = p%StiffTSS(J)*abs(p%DHNodes(J)) ! Side-to-side stiffness of tower element J + + DO I = 1,2 ! Loop through all tower DOFs in one direction + DO L = 1,2 ! Loop through all tower DOFs in one direction + p%KTFA (I,L) = p%KTFA (I,L) + ElStffFA *p%TwrFASF(I,J,2)*p%TwrFASF(L,J,2) + p%KTSS (I,L) = p%KTSS (I,L) + ElStffSS *p%TwrSSSF(I,J,2)*p%TwrSSSF(L,J,2) + ENDDO ! L - All tower DOFs in one direction + ENDDO ! I - through all tower DOFs in one direction + + + ! Integrate to find the gravitational-term of the generalized stiffness of the tower. + ! Ignore the cross-correlation terms of KTFAGrav (i.e. KTFAGrav(i,j) where i /= j) + ! and KTSSGrav since these terms will never be used. + + ElmntStff = -TMssAbvNd(J)*abs(p%DHNodes(J))*p%Gravity ! Gravitational stiffness of tower element J + + DO I = 1,2 ! Loop through all tower DOFs in one direction + KTFAGrav(I,I) = KTFAGrav(I,I) + ElmntStff*p%TwrFASF(I,J,1)**2 + KTSSGrav(I,I) = KTSSGrav(I,I) + ElmntStff*p%TwrSSSF(I,J,1)**2 + ENDDO + + + ! Integrate to find the tower axial reduction shape functions: + + DO I = 1,2 ! Loop through all tower DOFs in one direction + DO L = 1,2 ! Loop through all tower DOFs in one direction + AxRdTFA (I,L) = 0.5*p%DHNodes(J)*p%TwrFASF(I,J,1)*p%TwrFASF(L,J,1) + AxRdTSS (I,L) = 0.5*p%DHNodes(J)*p%TwrSSSF(I,J,1)*p%TwrSSSF(L,J,1) + + p%AxRedTFA(I,L,J) = AxRdTFA(I,L) + p%AxRedTSS(I,L,J) = AxRdTSS(I,L) + ENDDO ! L - All tower DOFs in one direction + ENDDO + + IF ( J /= 1 ) THEN ! All but the lowermost tower element + ! Add the effects from the (not yet used) portion of element J-1 + + DO I = 1,2 ! Loop through all tower DOFs in one direction + DO L = 1,2 ! Loop through all tower DOFs in one direction + p%AxRedTFA(I,L,J) = p%AxRedTFA(I,L,J) + p%AxRedTFA(I,L,J-1)+ AxRdTFAOld(I,L) + p%AxRedTSS(I,L,J) = p%AxRedTSS(I,L,J) + p%AxRedTSS(I,L,J-1)+ AxRdTSSOld(I,L) + ENDDO ! L - All tower DOFs in one direction + ENDDO + ENDIF + + + ! Store the AxRdTFA and AxRdTSS terms of the current element (these will be used for the next element) + + AxRdTFAOld = AxRdTFA + AxRdTSSOld = AxRdTSS + + + ENDDO ! J - Tower nodes / elements + + + ! Apply the modal stiffness tuners of the tower to KTFA() and KTSS(): + + DO I = 1,2 ! Loop through all tower DOFs in one direction + DO L = 1,2 ! Loop through all tower DOFs in one direction + p%KTFA(I,L) = SQRT( InputFileData%FAStTunr(I)*InputFileData%FAStTunr(L) )*p%KTFA(I,L) + + p%KTSS(I,L) = SQRT( InputFileData%SSStTunr(I)*InputFileData%SSStTunr(L) )*p%KTSS(I,L) + ENDDO ! L - All tower DOFs in one direction + ENDDO ! I - through all tower DOFs in one direction + + + ! Calculate the tower natural frequencies: + + DO I = 1,2 ! Loop through all tower DOFs in one direction + if ( EqualRealNos(( MTFA(I,I) - p%TwrTpMass ), 0.0_ReKi) ) then + p%FreqTFA(I,1) = NaN ! Avoid creating a divide by zero signal, but set p%FreqTFA(I,1) = NaN + else + p%FreqTFA(I,1) = Inv2Pi*SQRT( p%KTFA(I,I)/( MTFA(I,I) - p%TwrTpMass ) ) ! Natural tower I-fore-aft frequency w/o gravitational destiffening nor tower-top mass effects + end if + if ( EqualRealNos(( MTSS(I,I) - p%TwrTpMass ), 0.0_ReKi) ) then + p%FreqTSS(I,1) = NaN ! Avoid creating a divide by zero signal, but set p%FreqTFS(I,1) = NaN + else + p%FreqTSS(I,1) = Inv2Pi*SQRT( p%KTSS(I,I)/( MTSS(I,I) - p%TwrTpMass ) ) ! Natural tower I-side-to-side frequency w/o gravitational destiffening nor tower-top mass effects + end if + p%FreqTFA(I,2) = Inv2Pi*SQRT( ( p%KTFA(I,I) + KTFAGrav(I,I) )/MTFA(I,I) ) ! Natural tower I-fore-aft frequency w/ gravitational destiffening and tower-top mass effects + p%FreqTSS(I,2) = Inv2Pi*SQRT( ( p%KTSS(I,I) + KTSSGrav(I,I) )/MTSS(I,I) ) ! Natural tower I-side-to-side frequency w/ gravitational destiffening and tower-top mass effects + ENDDO ! I - All tower DOFs in one direction + + + ! Calculate the generalized damping of the tower: + + DO I = 1,2 ! Loop through all tower DOFs in one direction + DO L = 1,2 ! Loop through all tower DOFs in one direction + p%CTFA(I,L) = ( 0.01*InputFileData%TwrFADmp(L) )*p%KTFA(I,L)/( Pi*p%FreqTFA(L,1) ) + + p%CTSS(I,L) = ( 0.01*InputFileData%TwrSSDmp(L) )*p%KTSS(I,L)/( Pi*p%FreqTSS(L,1) ) + ENDDO ! L - All tower DOFs in one direction + ENDDO ! I - All tower DOFs in one direction + + + ! Calculate the tower shape functions (all derivatives) at the tower-top: + + p%TwrFASF(1,p%TTopNode,2) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwFAM1Sh(:), 2, ErrStat, ErrMsg ) + p%TwrFASF(2,p%TTopNode,2) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwFAM2Sh(:), 2, ErrStat, ErrMsg ) + p%TwrFASF(1,p%TTopNode,1) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwFAM1Sh(:), 1, ErrStat, ErrMsg ) + p%TwrFASF(2,p%TTopNode,1) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwFAM2Sh(:), 1, ErrStat, ErrMsg ) + p%TwrFASF(1,p%TTopNode,0) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwFAM1Sh(:), 0, ErrStat, ErrMsg ) + p%TwrFASF(2,p%TTopNode,0) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwFAM2Sh(:), 0, ErrStat, ErrMsg ) + + p%TwrSSSF(1,p%TTopNode,2) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwSSM1Sh(:), 2, ErrStat, ErrMsg ) + p%TwrSSSF(2,p%TTopNode,2) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwSSM2Sh(:), 2, ErrStat, ErrMsg ) + p%TwrSSSF(1,p%TTopNode,1) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwSSM1Sh(:), 1, ErrStat, ErrMsg ) + p%TwrSSSF(2,p%TTopNode,1) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwSSM2Sh(:), 1, ErrStat, ErrMsg ) + p%TwrSSSF(1,p%TTopNode,0) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwSSM1Sh(:), 0, ErrStat, ErrMsg ) + p%TwrSSSF(2,p%TTopNode,0) = SHP( 1.0_ReKi, p%TwrFlexL, InputFileData%TwSSM2Sh(:), 0, ErrStat, ErrMsg ) + + + ! Integrate to find the tower axial reduction shape functions at the tower-top: + + DO I = 1,2 ! Loop through all tower DOFs in one direction + DO L = 1,2 ! Loop through all tower DOFs in one direction + p%AxRedTFA(I,L,p%TTopNode) = p%AxRedTFA(I,L,p%TwrNodes)+ AxRdTFAOld(I,L) + p%AxRedTSS(I,L,p%TTopNode) = p%AxRedTSS(I,L,p%TwrNodes)+ AxRdTSSOld(I,L) + ENDDO ! L - All tower DOFs in one direction + ENDDO + + + ! Calculate the turbine mass: + + p%TurbMass = p%TwrTpMass + p%TwrMass + + + RETURN +END SUBROUTINE Coeff +``` \ No newline at end of file diff --git a/书籍/力学书籍/OpenFast/FASTKinetics/auto/meshmap.md b/书籍/力学书籍/OpenFast/FASTKinetics/auto/meshmap.md new file mode 100644 index 0000000..9419442 --- /dev/null +++ b/书籍/力学书籍/OpenFast/FASTKinetics/auto/meshmap.md @@ -0,0 +1,622 @@ + +```fortran + +!---------------------------------------------------------------------------------------------------------------------------------- +!bjj: maybe the MeshMapCreate routine shouldn't actually allocate arrays; allocate them in +! the "IF (RemapFlag)" sections so that if people add nodes during the simulation, the structures get reallocated to correct +! size? MeshMapCreate should maybe be MeshMapping_Init() and only check that fields are compatible, etc. +!---------------------------------------------------------------------------------------------------------------------------------- +!> This subroutine takes two meshes, determines the sizes required for the mapping data structure, and then +!! allocates the mappings (different for loads and motions/scalars). +SUBROUTINE MeshMapCreate( Src, Dest, MeshMap, ErrStat, ErrMsg ) + +! note that MeshMap%MapSrcToAugmt is allocated in Create_Augmented_Ln2_Src_Mesh() along with the Augmented_Ln2_Src Mesh + + TYPE(MeshType), INTENT(IN) :: Src !< source mesh + TYPE(MeshType), INTENT(IN) :: Dest !< destination mesh + + TYPE(MeshMapType), INTENT(INOUT) :: MeshMap !< mapping data structure + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables: + + INTEGER(IntKi) :: PointsInMap, PointsInTmpMap + INTEGER(IntKi) :: ElementNodes + LOGICAL :: MapCreated + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + CHARACTER(*), PARAMETER :: RoutineName = 'MeshMapCreate' + + + ErrStat = ErrID_None + ErrMsg = '' + + MapCreated = .FALSE. + + + IF ( .NOT. Dest%Committed .OR. .NOT. Src%Committed ) THEN + ErrStat = ErrID_Fatal + ErrMsg = " Both meshes must be committed before they can be mapped." + RETURN + END IF + + + ElementNodes = 1 + PointsInTmpMap = 0 + + !................................................ + ! Allocate the mapping for Motions and Scalars (if both meshes have some): + !................................................ + IF ( HasMotionFields(Src) .AND. HasMotionFields(Dest) ) THEN + + IF ( Src%ElemTable(ELEMENT_LINE2)%nelem > 0 ) THEN !Line2-to-Point and Line2-to-Line2 motion mapping + ElementNodes = 2 + END IF + + + ! for motion fields, every destination node is mapped to a source element or node + + PointsInMap = Dest%Nnodes + PointsInTmpMap = MAX(PointsInTmpMap,PointsInMap) + + IF ( PointsInMap < 1 ) THEN + CALL SetErrStat( ErrID_Fatal, 'MeshMap%MapMotions not allocated because no nodes were found to map.', ErrStat, ErrMsg, RoutineName) + ELSE + + ! Allocate the mapping structure: + ALLOCATE( MeshMap%MapMotions(PointsInMap), STAT=ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error trying to allocate MeshMap%MapMotions.', ErrStat, ErrMsg, RoutineName) + ELSE + MapCreated = .TRUE. + + ! set up the initial mappings so that we don't necessarially have to do this multiple times on the first time step (if calculating Jacobians) + IF ( Dest%ElemTable(ELEMENT_LINE2)%nelem > 0 ) THEN ! point-to-Line2 or Line2-to-Line2 + + IF ( Src%ElemTable(ELEMENT_LINE2)%nelem > 0 ) THEN ! Line2-to-Line2 + CALL CreateMotionMap_L2_to_L2( Src, Dest, MeshMap, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + ELSEIF ( Src%ElemTable(ELEMENT_POINT)%nelem > 0 ) THEN ! point-to-Line2 + CALL CreateMotionMap_P_to_L2( Src, Dest, MeshMap, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + + ELSEIF ( Dest%ElemTable(ELEMENT_POINT)%nelem > 0 ) THEN ! point-to-point or Line2-to-point + + IF ( Src%ElemTable(ELEMENT_POINT)%nelem > 0 ) THEN ! point-to-point + CALL CreateMotionMap_P_to_P( Src, Dest, MeshMap, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + ELSEIF ( Src%ElemTable(ELEMENT_LINE2)%nelem > 0 ) THEN ! Line2-to-point + CALL CreateMotionMap_L2_to_P(Src, Dest, MeshMap, ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + + END IF ! create initial mapping based on mesh element type + + END IF ! MapMotions created + + END IF ! Dest has nodes to map + + END IF !HasMotionFields + + + !................................................ + ! Allocate the mapping for Loads: + !................................................ + IF ( HasLoadFields(Src) .AND. HasLoadFields(Dest) ) THEN + + ! check that the appropriate combinations of source/destination force/moments exist: + IF ( Src%FieldMask(MASKID_Force) ) THEN + IF (.NOT. Dest%FieldMask(MASKID_Force) ) THEN + CALL SetErrStat( ErrID_Fatal, 'Destination mesh does not contain force but source mesh does.', ErrStat, ErrMsg, RoutineName) + END IF + IF (.NOT. Dest%FieldMask(MASKID_Moment) ) THEN + CALL SetErrStat( ErrID_Fatal, 'Destination mesh must contain moment when source mesh contains force.', ErrStat, ErrMsg, RoutineName) + END IF + END IF + IF ( Src%FieldMask(MASKID_Moment) ) THEN + IF (.NOT. Dest%FieldMask(MASKID_Moment) ) THEN + CALL SetErrStat( ErrID_Fatal, 'Destination mesh does not contain moment but source mesh does.', ErrStat, ErrMsg, RoutineName) + END IF + END IF + + + ! get size of mapping: + PointsInMap = Src%Nnodes + + IF ( PointsInMap < 1 ) THEN + CALL SetErrStat( ErrID_Fatal, 'MeshMap%MapLoads not allocated because no nodes were found to map.', ErrStat, ErrMsg, RoutineName) + ELSE + + ! Allocate the mapping structure: + ALLOCATE( MeshMap%MapLoads(PointsInMap), STAT=ErrStat2 ) + IF ( ErrStat2 /= 0 ) THEN + CALL SetErrStat( ErrID_Fatal, 'Error trying to allocate MeshMap%MapLoads.', ErrStat, ErrMsg, RoutineName) + ELSE + MapCreated = .TRUE. + + ! set up the initial mappings so that we don't necessarially have to do this multiple times on the first time step (if calculating Jacobians) + IF ( Dest%ElemTable(ELEMENT_LINE2)%nelem > 0 ) THEN ! point-to-Line2 or Line2-to-Line2 + + ElementNodes = 2 + + IF ( Src%ElemTable(ELEMENT_LINE2)%nelem > 0 ) THEN ! Line2-to-Line2 + CALL CreateLoadMap_L2_to_L2( Src, Dest, MeshMap, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + ELSEIF ( Src%ElemTable(ELEMENT_POINT)%nelem > 0 ) THEN ! point-to-Line2 + CALL CreateLoadMap_P_to_L2( Src, Dest, MeshMap, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + + ELSEIF ( Dest%ElemTable(ELEMENT_POINT)%nelem > 0 ) THEN ! point-to-point or Line2-to-point + + IF ( Src%ElemTable(ELEMENT_POINT)%nelem > 0 ) THEN ! point-to-point + CALL CreateLoadMap_P_to_P( Src, Dest, MeshMap, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + ELSEIF ( Src%ElemTable(ELEMENT_LINE2)%nelem > 0 ) THEN ! Line2-to-point + CALL CreateLoadMap_L2_to_P(Src, Dest, MeshMap, ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + + END IF ! create initial mapping based on mesh element type + + END IF ! MapLoads allocated + + END IF ! Src has nodes to transfer + + END IF ! HasLoadFields + + IF ( .NOT. MapCreated ) THEN + CALL SetErrStat( ErrID_Fatal, 'Neither MapMotions or MapLoads was allocated. Meshes may not have compatible fields for mapping.', ErrStat, ErrMsg, RoutineName) + RETURN + END IF + + + !................................................ + ! Allocate the DisplacedPosition field: + !................................................ + + IF (.NOT. ALLOCATED (MeshMap%DisplacedPosition)) THEN + CALL AllocAry( MeshMap%DisplacedPosition, 3, PointsInTmpMap, ElementNodes, 'MeshMap%DisplacedPosition', ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName) + END IF + + +END SUBROUTINE MeshMapCreate +``` + + +```fortran +!> This routine creates the mapping of motions between two meshes +SUBROUTINE CreateMotionMap_L2_to_L2( Src, Dest, MeshMap, ErrStat, ErrMsg ) + + TYPE(MeshType), INTENT(IN ) :: Src !< The source mesh + TYPE(MeshType), INTENT(IN ) :: Dest !< The destination mesh + TYPE(MeshMapType), INTENT(INOUT) :: MeshMap !< structure that contains data necessary to map these two meshes + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! Local variables: + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + + CALL CreateMapping_ProjectToLine2(Dest,Src, MeshMap%MapMotions, ELEMENT_LINE2, ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CreateMotionMap_L2_to_L2') + IF (ErrStat >= AbortErrLev) RETURN + +END SUBROUTINE CreateMotionMap_L2_to_L2 +``` + +```fortran +!> This routine projects Mesh1 onto a Line2 mesh (Mesh2) to find the element mappings between the two meshes. +SUBROUTINE CreateMapping_ProjectToLine2(Mesh1, Mesh2, NodeMap, Mesh1_TYPE, ErrStat, ErrMsg) + + TYPE(MeshType), INTENT(IN ) :: Mesh1 !< The mesh in the outer mapping loop (Dest for Motions/Scalars; Src for Loads) + TYPE(MeshType), INTENT(IN ) :: Mesh2 !< The mesh in the inner mapping loop (Src for Motions/Scalars; Dest for Loads) + + TYPE(MapType), INTENT(INOUT) :: NodeMap(:) !< The mapping from Src to Dest + + INTEGER(IntKi), INTENT(IN ) :: Mesh1_TYPE !< Type of Mesh1 elements to map + INTEGER(IntKi), PARAMETER :: Mesh2_TYPE = ELEMENT_LINE2 !< Type of Mesh2 elements on map (MUST BE ELEMENT_LINE2) + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + + ! local variables + +! INTEGER(IntKi) :: ErrStat2 ! Error status of the operation +! CHARACTER(ErrMsgLen) :: ErrMsg2 ! Error message if ErrStat2 /= ErrID_None +#ifdef DEBUG_MESHMAPPING + CHARACTER(200) :: DebugFileName ! File name for debugging file +#endif + CHARACTER(*), PARAMETER :: RoutineName = 'CreateMapping_ProjectToLine2' + + + REAL(ReKi) :: denom + REAL(ReKi) :: dist + REAL(ReKi) :: min_dist + REAL(ReKi) :: elem_position + REAL(SiKi) :: elem_position_SiKi + + REAL(ReKi) :: Mesh1_xyz(3) + + REAL(ReKi) :: n1_n2_vector(3) ! vector going from node 1 to node 2 in Line2 element + REAL(ReKi) :: n1_Point_vector(3) ! vector going from node 1 in Line 2 element to Destination Point + REAL(ReKi) :: tmp(3) ! temporary vector for cross product calculation + + + INTEGER(IntKi) :: iElem, iNode, i ! do-loop counter for elements on Mesh1, associated node(S) + INTEGER(IntKi) :: jElem ! do-loop counter for elements on Mesh2, associated node + + INTEGER(IntKi) :: n1, n2 ! nodes associated with an element + + LOGICAL :: found + LOGICAL :: on_element + REAL(ReKi) :: closest_elem_position + INTEGER(IntKi) :: closest_elem + REAL(ReKi) :: closest_elem_diff + REAL(ReKi) :: closest_elem_distance + +#ifdef DEBUG_MESHMAPPING + INTEGER(IntKi) :: Un ! unit number for debugging + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 +#endif + + + + ! initialization + ErrStat = ErrID_None + ErrMsg = "" + + + ! Map the source nodes to destination nodes: + do n1=1,size(NodeMap) + NodeMap(n1)%OtherMesh_Element = NODE_NOT_MAPPED ! initialize this so we know if we've mapped this node already (done only because we may have different elements) + end do !n1 + + + + do iElem = 1, Mesh1%ElemTable(Mesh1_TYPE)%nelem ! number of Mesh1_TYPE elements on Mesh1 + do iNode = 1, SIZE( Mesh1%ElemTable(Mesh1_TYPE)%Elements(iElem)%ElemNodes ) + i = Mesh1%ElemTable(Mesh1_TYPE)%Elements(iElem)%ElemNodes(iNode) ! the nodes on element iElem + IF ( NodeMap(i)%OtherMesh_Element > 0 ) CYCLE ! we already mapped this node; let's move on to the next iNode (or iElem) + + ! destination point + Mesh1_xyz = Mesh1%Position(:, i) + + found = .false. + min_dist = HUGE(min_dist) + + ! some values for finding mapping if there are some numerical issues + closest_elem_diff = HUGE(min_dist) + closest_elem = 0 + + do jElem = 1, Mesh2%ElemTable(Mesh2_TYPE)%nelem ! ELEMENT_LINE2 = Mesh2_TYPE + + ! write(*,*) 'i,jElem = ', i,jElem, 'found = ', found + + ! grab node numbers associated with the jElem_th element + n1 = Mesh2%ElemTable(Mesh2_TYPE)%Elements(jElem)%ElemNodes(1) + n2 = Mesh2%ElemTable(Mesh2_TYPE)%Elements(jElem)%ElemNodes(2) + + ! Calculate vectors used in projection operation + + n1_n2_vector = Mesh2%Position(:,n2) - Mesh2%Position(:,n1) + n1_Point_vector = Mesh1_xyz - Mesh2%Position(:,n1) + + denom = DOT_PRODUCT( n1_n2_vector, n1_n2_vector ) + IF ( EqualRealNos( denom, 0.0_ReKi ) ) THEN + CALL SetErrStat( ErrID_Fatal, 'Division by zero because Line2 element nodes are in same position.', ErrStat, ErrMsg, RoutineName) + RETURN + END IF + + ! project point onto line defined by n1 and n2 + + elem_position = DOT_PRODUCT(n1_n2_vector,n1_Point_vector) / denom + + ! note: i forumlated it this way because Fortran doesn't necessarially do shortcutting and I don't want to call EqualRealNos if we don't need it: + if ( elem_position .ge. 0.0_ReKi .and. elem_position .le. 1.0_ReKi ) then !we're ON the element (between the two nodes) + on_element = .true. + else + elem_position_SiKi = REAL( elem_position, SiKi ) + if (EqualRealNos( elem_position_SiKi, 1.0_SiKi )) then !we're ON the element (at a node) + on_element = .true. + elem_position = 1.0_ReKi + elseif (EqualRealNos( elem_position_SiKi, 0.0_SiKi )) then !we're ON the element (at a node) + on_element = .true. + elem_position = 0.0_ReKi + else !we're not on the element + on_element = .false. + + if (.not. found) then ! see if we have are very close to the end of an element (numerical roundoff?) + if ( elem_position_SiKi < 0.0_SiKi ) then + if ( -elem_position_SiKi < closest_elem_diff ) then + closest_elem_diff = -elem_position_SiKi + closest_elem = jElem + closest_elem_position = 0.0_ReKi + closest_elem_distance = sqrt(denom) * closest_elem_diff ! distance from end of element, in meters + end if + else + if ( elem_position_SiKi-1.0_SiKi < closest_elem_diff ) then + closest_elem_diff = elem_position_SiKi-1.0_SiKi + closest_elem = jElem + closest_elem_position = 1.0_ReKi + closest_elem_distance = sqrt(denom) * closest_elem_diff ! distance from end of element, in meters + end if + end if + end if + + end if + end if + + if (on_element) then + + ! calculate distance between point and line (note: this is actually the distance squared); + ! will only store information once we have determined the closest element + tmp = cross_product( n1_n2_vector, n1_Point_vector ) + dist = DOT_PRODUCT(tmp,tmp) / denom + + if (dist .lt. min_dist) then + found = .true. + min_dist = dist + + NodeMap(i)%OtherMesh_Element = jElem + NodeMap(i)%shape_fn(1) = 1.0_ReKi - elem_position + NodeMap(i)%shape_fn(2) = elem_position + + !NodeMap(i)%couple_arm = n1_Point_vector + + end if !the point is closest to this line2 element + + endif + + end do !jElem + + ! if failed to find an element that the Point projected into, throw an error + if (.not. found) then + if ( closest_elem_distance <= 7.5e-3 ) then ! if it is within 7.5mm of the end of an element, we'll accept it + NodeMap(i)%OtherMesh_Element = closest_elem + NodeMap(i)%shape_fn(1) = 1.0_ReKi - closest_elem_position + NodeMap(i)%shape_fn(2) = closest_elem_position + CALL SetErrStat( ErrID_Info, 'Found close value for node '//trim(num2Lstr(i))//'. ('//trim(num2lstr(closest_elem_distance))//' m)', ErrStat, ErrMsg, RoutineName) + end if + + if (NodeMap(i)%OtherMesh_Element .lt. 1 ) then + CALL SetErrStat( ErrID_Fatal, 'Node '//trim(num2Lstr(i))//' does not project onto any line2 element.' & + //' Closest distance is '//trim(num2lstr(closest_elem_distance))//' m.', ErrStat, ErrMsg, RoutineName) + +#ifdef DEBUG_MESHMAPPING + ! output some mesh information for debugging + CALL GetNewUnit(Un,ErrStat2,ErrMsg2) + DebugFileName='FAST_Meshes.'//trim(num2Lstr(Un))//'.dbg' + CALL OpenFOutFile(Un,DebugFileName,ErrStat2,ErrMsg2) + IF (ErrStat2 >= AbortErrLev) RETURN + + CALL SetErrStat( ErrID_Info, 'See '//trim(DebugFileName)//' for mesh debug information.', ErrStat, ErrMsg, RoutineName) + WRITE( Un, '(A,I5,A,I5,A,ES15.5,A)' ) 'Element ', closest_elem, ' is closest to node ', i, & + '. It has a relative position of ', closest_elem_diff, '.' + + WRITE( Un, '(A)') '************************************************** Mesh1 ***************************************************' + WRITE( Un, '(A)') 'Mesh1 is the destination mesh for transfer of motions/scalars; it is the source mesh for transfer of loads.' + WRITE( Un, '(A)') '************************************************************************************************************' + CALL MeshPrintInfo ( Un, Mesh1 ) + WRITE( Un, '(A)') '************************************************** Mesh2 ***************************************************' + WRITE( Un, '(A)') 'Mesh2 is the source mesh for transfer of motions/scalars; it is the destination mesh for transfer of loads.' + WRITE( Un, '(A)') '************************************************************************************************************' + CALL MeshPrintInfo ( Un, Mesh2 ) + ! CLOSE(Un) ! by not closing this, I can ensure unique file names. +#endif + + RETURN + endif + + end if !not found on projection to element + + end do !iNode + end do !iElem + +END SUBROUTINE CreateMapping_ProjectToLine2 +``` + +```fortran +SUBROUTINE CreateMotionMap_P_to_L2( Src, Dest, MeshMap, ErrStat, ErrMsg ) + + TYPE(MeshType), INTENT(IN ) :: Src ! The source mesh + TYPE(MeshType), INTENT(IN ) :: Dest ! The destination mesh + TYPE(MeshMapType), INTENT(INOUT) :: MeshMap + + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + ! Local variables: + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + + ! Each destination node (on a LINE2 mesh) needs a source + ! in following call, Dest is mesh to looped over, finding a corresponding point for each point in Src + CALL CreateMapping_NearestNeighbor( Dest, Src, MeshMap%MapMotions, ELEMENT_LINE2, ELEMENT_POINT, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CreateMotionMap_P_to_L2') + IF (ErrStat >= AbortErrLev) RETURN + + ! bjj: for consistant definition of couple_arm (i.e. p_ODR-p_OSR), let's multiply by -1 + do i=1,SIZE(MeshMap%MapMotions) + MeshMap%MapMotions(i)%couple_arm = -1._ReKi*MeshMap%MapMotions(i)%couple_arm + end do + + +END SUBROUTINE CreateMotionMap_P_to_L2 +``` + +```fortran + +!> This routine creates the node-to-node (nearest neighbor). We map FROM Mesh1 to Mesh2 +SUBROUTINE CreateMapping_NearestNeighbor( Mesh1, Mesh2, NodeMap, Mesh1_TYPE, Mesh2_TYPE, ErrStat, ErrMsg ) +!....................................................................................... + TYPE(MeshType), INTENT(IN ) :: Mesh1 !< The mesh in the outer mapping loop (Dest for Motions/Scalars; Src for Loads) + TYPE(MeshType), INTENT(IN ) :: Mesh2 !< The mesh in the inner mapping loop (Src for Motions/Scalars; Dest for Loads) + + TYPE(MapType), INTENT(INOUT) :: NodeMap(:) !< The mapping from Src to Dest + + INTEGER(IntKi), INTENT(IN ) :: Mesh1_TYPE !< Type of Mesh1 elements to map + INTEGER(IntKi), INTENT(IN ) :: Mesh2_TYPE !< Type of Mesh2 elements on map + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! local variables + + REAL(ReKi) :: dist + REAL(ReKi) :: min_dist + + REAL(ReKi) :: Mesh1_xyz(3) + REAL(ReKi) :: Mesh2_xyz(3) + + INTEGER(IntKi) :: point_with_min_dist + INTEGER(IntKi) :: iElem, iNode, i ! do-loop counter for elements on Mesh1, associated node(S) + INTEGER(IntKi) :: jElem, jNode, j ! do-loop counter for elements on Mesh2, associated node + + LOGICAL :: UseMesh2Node(Mesh2%NNodes) ! determines if the node on the second mesh is part of the mapping (i.e., contained in an element of the appropriate type) + + + ! initialization + ErrStat = ErrID_None + ErrMsg = "" + + ! Determine which nodes on mesh2 are going to be in the mapping + UseMesh2Node = .FALSE. + do jElem = 1, Mesh2%ElemTable(Mesh2_TYPE)%nelem ! number of point elements on Mesh2 + do jNode = 1, SIZE( Mesh2%ElemTable(Mesh2_TYPE)%Elements(jElem)%ElemNodes ) + UseMesh2Node( Mesh2%ElemTable(Mesh2_TYPE)%Elements(jElem)%ElemNodes(jNode) ) = .TRUE. + end do + end do + + ! Map the source nodes to destination nodes: + do i=1,size(NodeMap) + NodeMap(i)%OtherMesh_Element = NODE_NOT_MAPPED ! initialize this so we know if we've mapped this node already (done only because we may have different elements) + end do !n1 + + + do iElem = 1, Mesh1%ElemTable(Mesh1_TYPE)%nelem ! number of Mesh1_TYPE elements on Mesh1 = number of points on Mesh1 + do iNode = 1, SIZE( Mesh1%ElemTable(Mesh1_TYPE)%Elements(iElem)%ElemNodes ) + i = Mesh1%ElemTable(Mesh1_TYPE)%Elements(iElem)%ElemNodes(iNode) ! the nodes on element iElem + IF ( NodeMap(i)%OtherMesh_Element > 0 ) CYCLE ! we already mapped this node; let's move on + + + ! Find the nearest neighbor node for this particular node + + ! initialize minimum distance marker at some huge number + min_dist = HUGE(min_dist) + point_with_min_dist = 0 + + Mesh1_xyz = Mesh1%Position(:, i) + + do j = 1, Mesh2%NNodes + IF ( .NOT. UseMesh2Node(j) ) CYCLE !This node isn't part of the elements we're mapping + + ! destination point + Mesh2_xyz = Mesh2%Position(:, j) + + ! calculate distance between source and desination; will only store information once we have determined + ! the closest point + dist = sqrt( (Mesh1_xyz(1) - Mesh2_xyz(1))**2 & + + (Mesh1_xyz(2) - Mesh2_xyz(2))**2 & + + (Mesh1_xyz(3) - Mesh2_xyz(3))**2 ) + + if (dist .lt. min_dist) then + + min_dist = dist + point_with_min_dist = j + + !if (EqualRealNos(dist), 0.0_ReKi)) EXIT !we have an exact match so let's just stop looking + + endif + + end do !j + + if (point_with_min_dist .lt. 1 ) then + CALL SetErrStat( ErrID_Fatal, 'Failed to find destination point associated with source point.', ErrStat, ErrMsg, 'CreateMapping_NearestNeighbor') + RETURN + endif + + NodeMap(i)%OtherMesh_Element = point_with_min_dist !bjj: For consistency, I really wish we had used element numbers here instead.... + + NodeMap(i)%distance = min_dist + + NodeMap(i)%couple_arm = Mesh2%Position(:, point_with_min_dist) - Mesh1_xyz + !bjj: this is the negative of the case where it's Mesh2=src, so we'll have to multiply by -1 outside this routine if that's the case + + end do !iNode + end do !iElem + + +END SUBROUTINE CreateMapping_NearestNeighbor +``` + +```fortran +SUBROUTINE CreateMotionMap_P_to_P( Src, Dest, MeshMap, ErrStat, ErrMsg ) + + TYPE(MeshType), INTENT(IN ) :: Src ! The source mesh + TYPE(MeshType), INTENT(IN ) :: Dest ! The destination mesh + TYPE(MeshMapType), INTENT(INOUT) :: MeshMap + + INTEGER(IntKi), INTENT( OUT) :: ErrStat ! Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg ! Error message if ErrStat /= ErrID_None + + ! Local variables: + INTEGER(IntKi) :: i + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + ! in following call, Dest is mesh to looped over, finding a corresponding point for each point in Src + CALL CreateMapping_NearestNeighbor( Dest, Src, MeshMap%MapMotions, ELEMENT_POINT, ELEMENT_POINT, ErrStat2, ErrMsg2 ) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CreateMotionMap_P_to_P') + IF (ErrStat >= AbortErrLev) RETURN + + ! bjj: for consistant definition of couple_arm (i.e. p_ODR-p_OSR), let's multiply by -1 + do i=1,SIZE(MeshMap%MapMotions) + MeshMap%MapMotions(i)%couple_arm = -1.0_ReKi*MeshMap%MapMotions(i)%couple_arm + end do + +END SUBROUTINE CreateMotionMap_P_to_P +``` + +```fortran +SUBROUTINE CreateMotionMap_L2_to_P( Src, Dest, MeshMap, ErrStat, ErrMsg ) + + TYPE(MeshType), INTENT(IN ) :: Src !< The source mesh + TYPE(MeshType), INTENT(IN ) :: Dest !< The destination mesh + TYPE(MeshMapType), INTENT(INOUT) :: MeshMap !< mapping data structure + + INTEGER(IntKi), INTENT( OUT) :: ErrStat !< Error status of the operation + CHARACTER(*), INTENT( OUT) :: ErrMsg !< Error message if ErrStat /= ErrID_None + + ! Local variables: + INTEGER(IntKi) :: ErrStat2 + CHARACTER(ErrMsgLen) :: ErrMsg2 + + ErrStat = ErrID_None + ErrMsg = "" + + CALL CreateMapping_ProjectToLine2(Dest,Src, MeshMap%MapMotions, ELEMENT_POINT, ErrStat2, ErrMsg2) + CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, 'CreateMotionMap_L2_to_P') + !IF (ErrStat >= AbortErrLev) RETURN + +END SUBROUTINE CreateMotionMap_L2_to_P +``` \ No newline at end of file diff --git a/书籍/力学书籍/力学/Dynamics of Structures (Ray Clough, Joseph Penzien) (Z-Library)/auto/Chap 10 EVALUATION OF STRUCTURALPROPERTY MATRICES.md b/书籍/力学书籍/力学/Dynamics of Structures (Ray Clough, Joseph Penzien) (Z-Library)/auto/Chap 10 EVALUATION OF STRUCTURALPROPERTY MATRICES.md index 9f71597..1b29201 100644 --- a/书籍/力学书籍/力学/Dynamics of Structures (Ray Clough, Joseph Penzien) (Z-Library)/auto/Chap 10 EVALUATION OF STRUCTURALPROPERTY MATRICES.md +++ b/书籍/力学书籍/力学/Dynamics of Structures (Ray Clough, Joseph Penzien) (Z-Library)/auto/Chap 10 EVALUATION OF STRUCTURALPROPERTY MATRICES.md @@ -345,7 +345,7 @@ in which there are as many terms as there are degrees of freedom. The off-diagon If more than one translational degree of freedom is specified at any nodal point, the same point mass will be associated with each degree of freedom. On the other hand, the mass associated with any rotational degree of freedom will be zero because of the assumption that the mass is lumped in points which have no rotational inertia. (Of course, if a rigid mass having a finite rotational inertia is associated with a rotational degree of freedom, the diagonal mass coefficient for that degree of freedom would be the rotational inertia of the mass.) Thus the lumped-mass matrix is a diagonal matrix which will include zero diagonal elements for the rotational degrees of freedom, in general. 其中项数与自由度数相同。该矩阵的非对角项 $m_{i j}$ 为零,因为任何质点的加速度仅在该点产生惯性力。点 $i$ 处由于点 $i$ 的单位加速度产生的惯性力显然等于集中在该点的质量;因此,在集中质量系统中,质量影响系数 $m_{i i}=m_{i}$。 -如果在任何节点处指定了多个平移自由度,则相同的质点质量将与每个自由度相关联。另一方面,与任何旋转自由度相关联的质量将为零,因为假设质量集中在没有转动惯量的点上。(当然,如果一个具有有限转动惯量的刚性质量与一个旋转自由度相关联,那么该自由度的对角质量系数将是该质量的转动惯量。)因此,集中质量矩阵是一个对角矩阵,通常会包含旋转自由度的零对角元素。 +**如果在任何节点处指定了多个平移自由度,则相同的质点质量将与每个自由度相关联。另一方面,与任何旋转自由度相关联的质量将为零,因为假设质量集中在没有转动惯量的点上。(当然,如果一个具有有限转动惯量的刚性质量与一个旋转自由度相关联,那么该自由度的对角质量系数将是该质量的转动惯量。)因此,集中质量矩阵是一个对角矩阵,通常会包含旋转自由度的零对角元素。** ? ## Consistent-Mass Matrix一致质量矩阵 Making use of the finite-element concept, it is possible to evaluate mass influence coefficients for each element of a structure by a procedure similar to the analysis of element stiffness coefficients. Consider, for example, the nonuniform beam segment shown in Fig. 10-7, which may be assumed to be the same as that of Fig. 10-4. The degrees of freedom of the segment are the translation and rotation at each end, and it will be assumed that the displacements within the span are defined by the same interpolation functions $\psi_{i}(x)$ used in deriving the element stiffness. diff --git a/多体+耦合求解器/ElastoDyn问题 NREL Forum.md b/多体+耦合求解器/ElastoDyn问题 NREL Forum.md new file mode 100644 index 0000000..d1e6a76 --- /dev/null +++ b/多体+耦合求解器/ElastoDyn问题 NREL Forum.md @@ -0,0 +1,12 @@ + +不支持prebend +# [Out-of-plane tip displacements](https://forums.nrel.gov/t/out-of-plane-tip-displacements/7037) +[[20260120_093252__[[meshmap]]分析SUBROUTINE_MeshMapCreate的实现方法and预弯]] + +# [Comparing ElastoDyn with BeamDyn for blade tip deformations](https://forums.nrel.gov/t/comparing-elastodyn-with-beamdyn-for-blade-tip-deformations/4774) + + + + +# [Deflection of ElastoDyn](https://forums.nrel.gov/t/deflection-of-elastodyn/2233) + diff --git a/多体+耦合求解器/多体理论框架.canvas b/多体+耦合求解器/多体理论框架.canvas deleted file mode 100644 index 221b02d..0000000 --- a/多体+耦合求解器/多体理论框架.canvas +++ /dev/null @@ -1,55 +0,0 @@ -{ - "nodes":[ - {"id":"9461f7dd96103316","type":"text","text":"Kane方法","x":-120,"y":-280,"width":250,"height":50}, - {"id":"0c8534c8ba68c9a6","type":"text","text":"**广义**主动力","x":-280,"y":-140,"width":250,"height":50}, - {"id":"5eaa425c204bf600","type":"text","text":"**广义**惯性力","x":40,"y":-140,"width":250,"height":50}, - {"id":"e398416e55019686","type":"text","text":"运动学","x":-210,"y":220,"width":250,"height":60}, - {"id":"38d3d1a313c094ee","type":"text","text":"广义坐标","x":-280,"y":340,"width":250,"height":60}, - {"id":"8ec17237cebe7433","type":"text","text":"广义速率","x":60,"y":340,"width":250,"height":60}, - {"id":"7351d2bbb065d539","type":"text","text":"动力学 ","x":-210,"y":110,"width":250,"height":60}, - {"id":"da500b2b12ed0901","type":"text","text":"填充augmat矩阵","x":290,"y":-30,"width":250,"height":60}, - {"id":"20ce8d75f0f35588","type":"text","text":"解出来q_dot ---u","x":580,"y":-30,"width":250,"height":60}, - {"id":"6094c53caf966263","type":"text","text":"由F + F^* 的形式转换到 [C(q,t)],{-f(qd,q,t)}形式 ","x":-165,"y":-40,"width":340,"height":80}, - {"id":"c20eeff7484d8a39","type":"text","text":"叠加法","x":-275,"y":560,"width":250,"height":60}, - {"id":"a729b7930412f0b1","type":"text","text":"需要保持边界条件一致","x":60,"y":560,"width":250,"height":60}, - {"id":"d405163cb9ecd804","type":"text","text":"叶片多段拆分,小段做模态叠加?","x":60,"y":670,"width":250,"height":60}, - {"id":"4a08e20366911d68","type":"text","text":"v1pt_theory","x":290,"y":140,"width":250,"height":60}, - {"id":"6e5a6a3cdd47bd52","type":"text","text":"v2pt_theory","x":290,"y":207,"width":250,"height":60}, - {"id":"4bfacdf3ddedbdec","type":"text","text":"柔性体 / 连续体","x":-340,"y":960,"width":250,"height":60}, - {"id":"ae48e80ccd92bffa","type":"text","text":"连续体振动","x":60,"y":960,"width":250,"height":60}, - {"id":"ed5a265dc4b72aaa","type":"text","text":"连续体动力学","x":420,"y":960,"width":250,"height":60}, - {"id":"fc13b731983ac384","type":"text","text":"浮动坐标系","x":-340,"y":1181,"width":250,"height":60}, - {"id":"df8e8a93ea4af203","x":984,"y":-235,"width":250,"height":60,"type":"text","text":"叶片"}, - {"id":"7dc483819d8b527b","x":1280,"y":-235,"width":250,"height":60,"type":"text","text":"轮毂"}, - {"id":"c02c22667637367f","x":1580,"y":-235,"width":250,"height":60,"type":"text","text":"机舱"}, - {"id":"623ac90ce5bad160","x":1580,"y":-60,"width":250,"height":60,"type":"text","text":"塔架"}, - {"id":"0324f23e7dc78d68","x":1580,"y":55,"width":250,"height":60,"type":"text","text":"机舱"}, - {"id":"ba5c15a27611709c","x":1580,"y":-150,"width":250,"height":60,"type":"text","text":"偏航轴承"}, - {"id":"6c3a6982a53e7df9","x":984,"y":177,"width":250,"height":60,"type":"text","text":"刚体部件:"}, - {"id":"f3c36900dd3ed9d1","x":1280,"y":177,"width":250,"height":60,"type":"text","text":"刚体的广义主动力、惯性力公式"}, - {"id":"b624e8c6302b9a1c","x":984,"y":310,"width":250,"height":60,"type":"text","text":"叶片、塔架"}, - {"id":"1054909d642ce071","x":1280,"y":310,"width":250,"height":60,"type":"text","text":"广义惯性力:质点广义惯性力公式 积分"}, - {"id":"1e1a1a0d67920443","x":1280,"y":420,"width":250,"height":60,"type":"text","text":"广义主动力:由势能dV/dq_r"}, - {"id":"092cf6719d47d01d","x":1280,"y":530,"width":250,"height":60,"type":"text","text":"弹性恢复力、阻尼、重力、气动力"}, - {"id":"32b762bd2a4b0d66","x":984,"y":640,"width":250,"height":60,"type":"text","text":"传动链、偏航"}, - {"id":"14a4450243ca9953","x":1620,"y":530,"width":250,"height":60,"type":"text","text":"原理呢?"} - ], - "edges":[ - {"id":"647c1b45edc92b02","fromNode":"9461f7dd96103316","fromSide":"bottom","toNode":"0c8534c8ba68c9a6","toSide":"top"}, - {"id":"e3d4293dd3262f2d","fromNode":"9461f7dd96103316","fromSide":"bottom","toNode":"5eaa425c204bf600","toSide":"top"}, - {"id":"9a803fcaec81414e","fromNode":"38d3d1a313c094ee","fromSide":"right","toNode":"8ec17237cebe7433","toSide":"left"}, - {"id":"7ff52c30a0b0347d","fromNode":"a729b7930412f0b1","fromSide":"bottom","toNode":"d405163cb9ecd804","toSide":"top"}, - {"id":"d97ef554530b15b5","fromNode":"c20eeff7484d8a39","fromSide":"right","toNode":"a729b7930412f0b1","toSide":"left"}, - {"id":"034d145edd7cfce0","fromNode":"0c8534c8ba68c9a6","fromSide":"bottom","toNode":"6094c53caf966263","toSide":"top"}, - {"id":"da18b7fa4859fa6f","fromNode":"5eaa425c204bf600","fromSide":"bottom","toNode":"6094c53caf966263","toSide":"top"}, - {"id":"5d5f4fef281a656e","fromNode":"6094c53caf966263","fromSide":"right","toNode":"da500b2b12ed0901","toSide":"left"}, - {"id":"5573fa12a3a02ee0","fromNode":"da500b2b12ed0901","fromSide":"right","toNode":"20ce8d75f0f35588","toSide":"left"}, - {"id":"c4828432b71fd99a","fromNode":"4bfacdf3ddedbdec","fromSide":"right","toNode":"ae48e80ccd92bffa","toSide":"left"}, - {"id":"8ded09c7902a30b6","fromNode":"ae48e80ccd92bffa","fromSide":"right","toNode":"ed5a265dc4b72aaa","toSide":"left"}, - {"id":"4818c7bc8aa99b57","fromNode":"b624e8c6302b9a1c","fromSide":"right","toNode":"1054909d642ce071","toSide":"left"}, - {"id":"d58b296db32dc932","fromNode":"1054909d642ce071","fromSide":"bottom","toNode":"1e1a1a0d67920443","toSide":"top"}, - {"id":"f88001eedfed69b8","fromNode":"1e1a1a0d67920443","fromSide":"bottom","toNode":"092cf6719d47d01d","toSide":"top"}, - {"id":"d0bfe0faa41e4e2f","fromNode":"6c3a6982a53e7df9","fromSide":"right","toNode":"f3c36900dd3ed9d1","toSide":"left"}, - {"id":"14130329273bf6fc","fromNode":"092cf6719d47d01d","fromSide":"right","toNode":"14a4450243ca9953","toSide":"left"} - ] -} \ No newline at end of file diff --git a/多体+耦合求解器/多体理论框架及ED求解方法.canvas b/多体+耦合求解器/多体理论框架及ED求解方法.canvas new file mode 100644 index 0000000..1ddb12c --- /dev/null +++ b/多体+耦合求解器/多体理论框架及ED求解方法.canvas @@ -0,0 +1,160 @@ +{ + "nodes":[ + {"id":"9461f7dd96103316","type":"text","text":"Kane方法","x":-120,"y":-280,"width":250,"height":50}, + {"id":"0c8534c8ba68c9a6","type":"text","text":"**广义**主动力","x":-280,"y":-140,"width":250,"height":50}, + {"id":"5eaa425c204bf600","type":"text","text":"**广义**惯性力","x":40,"y":-140,"width":250,"height":50}, + {"id":"e398416e55019686","type":"text","text":"运动学","x":-210,"y":220,"width":250,"height":60}, + {"id":"38d3d1a313c094ee","type":"text","text":"广义坐标","x":-280,"y":340,"width":250,"height":60}, + {"id":"8ec17237cebe7433","type":"text","text":"广义速率","x":60,"y":340,"width":250,"height":60}, + {"id":"7351d2bbb065d539","type":"text","text":"动力学 ","x":-210,"y":110,"width":250,"height":60}, + {"id":"da500b2b12ed0901","type":"text","text":"填充augmat矩阵","x":290,"y":-30,"width":250,"height":60}, + {"id":"20ce8d75f0f35588","type":"text","text":"解出来q_dot ---u","x":580,"y":-30,"width":250,"height":60}, + {"id":"6094c53caf966263","type":"text","text":"由F + F* 的形式转换到 [C(q,t)],{-f(qd,q,t)}形式 ","x":-165,"y":-40,"width":340,"height":80}, + {"id":"c20eeff7484d8a39","type":"text","text":"叠加法","x":-275,"y":560,"width":250,"height":60}, + {"id":"a729b7930412f0b1","type":"text","text":"需要保持边界条件一致","x":60,"y":560,"width":250,"height":60}, + {"id":"d405163cb9ecd804","type":"text","text":"叶片多段拆分,小段做模态叠加?","x":60,"y":670,"width":250,"height":60}, + {"id":"4a08e20366911d68","type":"text","text":"v1pt_theory","x":290,"y":140,"width":250,"height":60}, + {"id":"6e5a6a3cdd47bd52","type":"text","text":"v2pt_theory","x":290,"y":207,"width":250,"height":60}, + {"id":"4bfacdf3ddedbdec","type":"text","text":"柔性体 / 连续体","x":-340,"y":960,"width":250,"height":60}, + {"id":"ae48e80ccd92bffa","type":"text","text":"连续体振动","x":60,"y":960,"width":250,"height":60}, + {"id":"ed5a265dc4b72aaa","type":"text","text":"连续体动力学","x":420,"y":960,"width":250,"height":60}, + {"id":"fc13b731983ac384","type":"text","text":"浮动坐标系","x":-340,"y":1181,"width":250,"height":60}, + {"id":"df8e8a93ea4af203","type":"text","text":"叶片","x":984,"y":-235,"width":250,"height":60}, + {"id":"7dc483819d8b527b","type":"text","text":"轮毂","x":1280,"y":-235,"width":250,"height":60}, + {"id":"c02c22667637367f","type":"text","text":"机舱","x":1580,"y":-235,"width":250,"height":60}, + {"id":"623ac90ce5bad160","type":"text","text":"塔架","x":1580,"y":-60,"width":250,"height":60}, + {"id":"0324f23e7dc78d68","type":"text","text":"机舱","x":1580,"y":55,"width":250,"height":60}, + {"id":"ba5c15a27611709c","type":"text","text":"偏航轴承","x":1580,"y":-150,"width":250,"height":60}, + {"id":"6c3a6982a53e7df9","type":"text","text":"刚体部件:","x":984,"y":177,"width":250,"height":60}, + {"id":"f3c36900dd3ed9d1","type":"text","text":"刚体的广义主动力、惯性力公式","x":1280,"y":177,"width":250,"height":60}, + {"id":"b624e8c6302b9a1c","type":"text","text":"叶片、塔架","x":984,"y":310,"width":250,"height":60}, + {"id":"1054909d642ce071","type":"text","text":"广义惯性力:质点广义惯性力公式 积分","x":1280,"y":310,"width":250,"height":60}, + {"id":"1e1a1a0d67920443","type":"text","text":"广义主动力:由势能dV/dq_r","x":1280,"y":420,"width":250,"height":60}, + {"id":"092cf6719d47d01d","type":"text","text":"弹性恢复力、阻尼、重力、气动力","x":1280,"y":530,"width":250,"height":60}, + {"id":"32b762bd2a4b0d66","type":"text","text":"传动链、偏航","x":984,"y":640,"width":250,"height":60}, + {"id":"14a4450243ca9953","type":"text","text":"原理呢?","x":1620,"y":530,"width":250,"height":60}, + {"id":"5ed3765756616b02","type":"text","text":"叶片","x":-936,"y":1420,"width":250,"height":60}, + {"id":"9a7256948b4e439c","type":"text","text":"轮毂","x":-640,"y":1420,"width":250,"height":60}, + {"id":"db5161e16a8e2c3f","type":"text","text":"机舱","x":-340,"y":1420,"width":250,"height":60}, + {"id":"95eb99b9b0299f2f","type":"text","text":"塔架","x":-340,"y":1595,"width":250,"height":60}, + {"id":"a2e90c49290ecb52","type":"text","text":"偏航轴承","x":-340,"y":1505,"width":250,"height":60}, + {"id":"cccd4482e817fca4","type":"text","text":"$$\n{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 \\quad (i, j = 1, 2) \\tag{9}\n$$","x":-180,"y":1855,"width":980,"height":130}, + {"id":"722e4b9c310e6d2a","type":"text","text":"$$\nEI^{B1F}(r) = AdjFlSt^{B1} \\cdot FlpStff^{B1}(r) \\tag{10}\n$$","x":-180,"y":2050,"width":980,"height":80}, + {"id":"50e241bef2144ea1","type":"text","text":"$$\n\\frac{d^2 \\phi_i^{B1F}(r)}{dr^2} \\frac{d^2 \\phi_j^{B1F}(r)}{dr^2}\n$$","x":200,"y":2190,"width":220,"height":120}, + {"id":"f65edb48b74e18d7","type":"text","text":"叶片广义挥舞刚度","x":-540,"y":1904,"width":250,"height":32,"color":"2"}, + {"id":"e0d016f4bb106554","type":"text","text":"- 需要叶片挥舞刚度","x":-540,"y":2072,"width":250,"height":36}, + {"id":"a9889437875a9263","type":"text","text":"- 模态形状二阶导","x":-540,"y":2232,"width":250,"height":36}, + {"id":"da8b0f86919e99d9","type":"text","text":"$$\n\\left[ \\frac{d^2 \\phi_{1}^{B1E}(r)}{dr^2} \\right]^2\n$$","x":10,"y":2710,"width":220,"height":120}, + {"id":"6454ea0b5f37aafa","type":"text","text":"- 模态形状二阶导","x":-540,"y":2752,"width":250,"height":36}, + {"id":"36c9ab3fd7a0a402","type":"text","text":"- 需要叶片挥舞刚度","x":-540,"y":2592,"width":250,"height":36}, + {"id":"ab5c75b7401fb031","type":"text","text":"叶片广义摆振刚度","x":-540,"y":2424,"width":250,"height":32,"color":"2"}, + {"id":"da00f9548457388f","type":"text","text":"$$\n{k'}_{11}^{B1E} = \\int_{0}^{BldFlexL} EI^{B1E}(r) \\left[ \\frac{d^2 \\phi_{1}^{B1E}(r)}{dr^2} \\right]^2 dr \\tag{11}\n$$","x":-180,"y":2380,"width":600,"height":120}, + {"id":"a20bd9b934093730","type":"text","text":"$$\nEI^{B1E}(r) = AdjEdSt^{B1} \\cdot EdgStff^{B1}(r) \\tag{12}\n$$","x":-180,"y":2570,"width":560,"height":80}, + {"id":"c477cd2a76cd46fb","x":-540,"y":3101,"width":250,"height":60,"type":"text","text":"- 模态形状一阶导"}, + {"id":"2ee598faf0603188","x":-540,"y":2921,"width":250,"height":83,"color":"2","type":"text","text":"离心刚化效应引起的刚度项"}, + {"id":"dcd9236bd7c84bd4","type":"text","text":"叶片质量属性","x":-540,"y":3356,"width":250,"height":32,"color":"2"}, + {"id":"ebc5c6d7451acc3b","type":"text","text":"- 叶片质量","x":-540,"y":3454,"width":250,"height":36}, + {"id":"a49465d6a6a3c3c2","type":"text","text":"- 叶片一阶矩","x":-540,"y":3534,"width":250,"height":36}, + {"id":"11e198e842aadec4","type":"text","text":"- 叶片质心","x":-540,"y":3853,"width":250,"height":36}, + {"id":"7f6f9185b340d930","type":"text","text":"- 风轮质量","x":-540,"y":3954,"width":250,"height":36}, + {"id":"5a48574ff6eeda7e","type":"text","text":"- 风轮惯性","x":-540,"y":4054,"width":250,"height":36}, + {"id":"987e81ef1f1995b3","type":"text","text":"- 叶片二阶矩","x":-540,"y":3614,"width":250,"height":36}, + {"id":"c4978e46cf739ba4","x":-180,"y":2885,"width":820,"height":346,"type":"text","text":"```rust\nelmnt_stff = f_mom_abv_nd[[k, j]] * p.dr_nodes[j] * p.rot_speed.powi(2);\n\nshape1 = shp_array(p.r_nodes_norm[j], p.bld_flex_l, &p.bld_fl1_sh.slice(s![.., k]).to_owned(), 1);\n\nshape2 = shp_array(p.r_nodes_norm[j], p.bld_flex_l, &p.bld_fl2_sh.slice(s![.., k]).to_owned(), 1);\n\nk_bf_cent[[k, 0, 0]] += elmnt_stff * shape1 * shape1;\n\nk_bf_cent[[k, 1, 1]] += elmnt_stff * shape2 * shape2;\n\nshape = shp_array(p.r_nodes_norm[j], p.bld_flex_l, &p.bld_edg_sh.slice(s![.., k]).to_owned(), 1);\n\nk_be_cent[[k, 0, 0]] += elmnt_stff * shape * shape;\n```"}, + {"id":"c29809ca3c70881b","type":"text","text":" ```fortran\n p%BldMass (K) = p%TipMass(K)\n p%FirstMom (K) = p%TipMass(K)*p%BldFlexL\n p%SecondMom(K) = p%TipMass(K)*p%BldFlexL*p%BldFlexL\n ...\n p%BElmntMass(J,K) = p%MassB(K,J)*p%DRNodes(J)\n ...\n p%BldMass (K) = p%BldMass (K) + p%BElmntMass(J,K)\n p%FirstMom (K) = p%FirstMom (K) + p%BElmntMass(J,K)*p%RNodes(J)\n p%SecondMom(K) = p%SecondMom(K) + p%BElmntMass(J,K)*p%RNodes(J)*p%RNodes(J)\n \n ```","x":-180,"y":3320,"width":789,"height":460}, + {"id":"253044dc6cebe206","type":"text","text":"```rust\np.bld_cg[k] = p.first_mom[k] / p.bld_mass[k];\n\np.rot_mass += p.bld_mass[k];\n\np.rot_iner += (p.second_mom[k] + p.bld_mass[k] * p.hub_rad * (2.0 * p.bld_cg[k] + p.hub_rad)) * p.cos_pre_c[k].powi(2);\n```\n","x":-156,"y":3853,"width":796,"height":237}, + {"id":"9a824939bad661d2","x":-2120,"y":2252,"width":250,"height":36,"type":"text","text":"- 摆振广义质量"}, + {"id":"8fa04043b651b57e","x":-2120,"y":2394,"width":250,"height":36,"type":"text","text":"- 模态形状0阶导"}, + {"id":"34fed438f96dfa4c","x":-2120,"y":2540,"width":250,"height":60,"color":"2","type":"text","text":"固有频率"}, + {"id":"9005abbfdd8f3246","x":-2120,"y":2660,"width":250,"height":60,"type":"text","text":"挥舞固有频率"}, + {"id":"8944328366cdad0c","x":-2120,"y":2780,"width":250,"height":69,"type":"text","text":"考虑叶尖质量、离心刚化"}, + {"id":"a96110788e264552","x":-2120,"y":3180,"width":250,"height":60,"type":"text","text":"摆振固有频率"}, + {"id":"6f03c475fcf16a01","type":"text","text":"考虑叶尖质量、离心刚化","x":-2120,"y":3320,"width":250,"height":69}, + {"id":"f1cd43613a1fdfa5","type":"text","text":"广义质量","x":-2120,"y":1996,"width":250,"height":32,"color":"2"}, + {"id":"5b82d2f5eb26eefc","type":"text","text":"- 挥舞广义质量","x":-2120,"y":2094,"width":250,"height":36}, + {"id":"5d4daed7f83a3fa5","x":-2938,"y":2057,"width":640,"height":110,"type":"text","text":"$$\nm_{ij}^{\\prime B1F} = \\int_{0}^{BldFlexL} \\mu^{B1}(r) \\phi_i^{B1F}(r) \\phi_j^{B1F}(r) \\, dr \\quad (i, j = 1, 2) \\tag{16}\n$$"}, + {"id":"44300ab8ae0139cc","x":-2618,"y":2630,"width":320,"height":120,"type":"text","text":"$$\nf_i^{\\prime B1F} = \\frac{1}{2\\pi} \\sqrt{\\frac{k_{ii}^{\\prime B1F}}{m_{ii}^{\\prime B1F}}} \\tag{14}\n$$"}, + {"id":"0bc6d2d448f012fd","x":-3014,"y":2780,"width":716,"height":315,"type":"text","text":"```rust\n// Natural blade I-flap frequency w/o centrifugal stiffening nor     tip mass effects\n\np.freq_bf[[k, i, 0]] = INV2PI * (p.kbf[[k, i, i]] / (m_bf[[k, i, i]] - p.tip_mass[k])).sqrt();\n\n// Natural blade I-flap frequency w/o centrifugal stiffening, but w/ tip mass effects\n\np.freq_bf[[k, i, 1]] = INV2PI * (p.kbf[[k, i, i]] / m_bf[[k, i, i]]).sqrt();\n\n// Natural blade I-flap frequency w/  centrifugal stiffening and     tip mass effects\n\np.freq_bf[[k, i, 2]] = INV2PI * ((p.kbf[[k, i, i]] + k_bf_cent[[k, i, i]]) / m_bf[[k, i, i]]).sqrt();\n```"}, + {"id":"5047212eb42c9e69","type":"text","text":"$$\nf_i^{\\prime B1E} = \\frac{1}{2\\pi} \\sqrt{\\frac{k_{ii}^{\\prime B1E}}{m_{ii}^{\\prime B1E}}} \\tag{15}\n$$","x":-2618,"y":3150,"width":320,"height":120}, + {"id":"f5ccbef2e5e250b9","type":"text","text":"```rust\n// Natural blade 1-edge frequency w/o centrifugal stiffening nor      tip mass effects\n\np.freq_be[[k, 0, 0]] = INV2PI * (p.kbe[[k, 0, 0]] / (m_be[[k, 0, 0]] - p.tip_mass[k])).sqrt();\n\n// Natural Blade 1-edge frequency w/o  centrifugal stiffening, but w/ tip mass effects\n\np.freq_be[[k, 0, 1]] = INV2PI * (p.kbe[[k, 0, 0]] / m_be[[k, 0, 0]]).sqrt();\n\n// Natural Blade 1-edge frequency w/  centrifugal stiffening and      tip mass effects\n\np.freq_be[[k, 0, 2]] = INV2PI * ((p.kbe[[k, 0, 0]] + k_be_cent[[k, 0, 0]]) / m_be[[k, 0, 0]]).sqrt();\n```","x":-3014,"y":3320,"width":716,"height":315}, + {"id":"b5bee6a3e7c29d31","type":"text","text":"**叶片广义参数计算**","x":-1440,"y":2916,"width":250,"height":93,"color":"1"}, + {"id":"d89b6477389b9a45","x":-2774,"y":2196,"width":476,"height":112,"type":"text","text":"$$\nm_{11}^{\\prime B1E} = \\int_{0}^{BldFlexL} \\mu^{B1}(r) \\left[ \\phi_1^{B1E}(r) \\right]^2 dr \\tag{17}\n$$"}, + {"id":"d1cb8d99b00c07c8","x":-3022,"y":3699,"width":724,"height":203,"type":"text","text":"$$\n\\left. F_r \\right|_{DampB1} =\n\\begin{cases}\n-\\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 \\\\\n-\\frac{\\zeta_1^{B1E} {k'}_{11}^{B1E}}{\\pi f^{\\prime B 1 E}_1} \\dot{q}_{B1E1} & \\text{for } r = B1E1 \\\\\n-\\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 \\\\\n0 & \\text{otherwise}\n\\end{cases} \\tag{13}\n$$"}, + {"id":"204d6c2f3ec03ac0","x":-2120,"y":3771,"width":250,"height":60,"color":"2","type":"text","text":"广义阻尼"}, + {"id":"1684e3f8b6f17829","type":"text","text":"挥舞和摆振方向结构阻尼比","x":-2120,"y":3980,"width":250,"height":69}, + {"id":"b1dddd3ed142c348","x":-2600,"y":3973,"width":302,"height":84,"type":"text","text":"$\\zeta_{i}^{BIF} = BldFlDmp^{B1}(i)/100$\n$\\zeta_{i}^{BIE} = BldEdDmp^{B1}(i)/100$"}, + {"id":"c328cec51da1530b","x":-2963,"y":4080,"width":665,"height":230,"type":"text","text":" ```fortran\n\tp%CBF(K,I,L) = ( 0.01*p%BldFDamp(K,L) )*p%KBF(K,I,L)/( Pi*p%FreqBF(K,L,1) )\n\tp%CBE(K,1,1) = ( 0.01*p%BldEDamp(K,1) )*p%KBE(K,1,1)/( Pi*p%FreqBE(K,1,1) )\n ``` "}, + {"id":"169bd99d304f6f85","x":-2120,"y":4165,"width":250,"height":60,"type":"text","text":"广义阻尼系数"}, + {"id":"cd865939df274ef7","x":-3291,"y":4420,"width":993,"height":623,"type":"text","text":" ```fortran\n ! Calculate the 2nd derivatives of the twisted shape functions:\n Shape = SHP( p%RNodesNorm(J), p%BldFlexL, p%BldFl1Sh(:,K), 2, ErrStat, ErrMsg )\n p%TwistedSF(K,1,1,J,2) = Shape*p%CThetaS(K,J)\n ...\n ! Integrate to find the 1st derivatives of the twisted shape functions:\n TwstdSF ( I,L, 1) = p%TwistedSF(K,I,L,J,2)*0.5*p%DRNodes(J)\n p%TwistedSF (K,I,L,J,1) = TwstdSF ( I,L, 1)\n ...\n ! Integrate to find the twisted shape functions themselves (i.e., their zeroeth derivative):\n TwstdSF ( I,L, 0) = p%TwistedSF(K,I,L,J,1)*0.5*p%DRNodes(J)\n p%TwistedSF (K,I,L,J,0) = TwstdSF ( I,L, 0)\n ...\n ! Integrate to find the blade axial reduction shape functions:\n AxRdBld ( I,L ) = 0.5*p%DRNodes(J)*( &\n p%TwistedSF(K,1,I,L,1)*p%TwistedSF(K,1,L,J,1) &\n + p%TwistedSF(K,2,I,L,1)*p%TwistedSF(K,2,L,J,1) )\n p%AxRedBld (K,I,L,J) = AxRdBld(I,L)\n ```"}, + {"id":"43c52f1d3f4f4337","x":-2120,"y":4580,"width":250,"height":60,"color":"4","type":"text","text":"扭转形状函数和轴向缩短系数"} + ], + "edges":[ + {"id":"647c1b45edc92b02","fromNode":"9461f7dd96103316","fromSide":"bottom","toNode":"0c8534c8ba68c9a6","toSide":"top"}, + {"id":"e3d4293dd3262f2d","fromNode":"9461f7dd96103316","fromSide":"bottom","toNode":"5eaa425c204bf600","toSide":"top"}, + {"id":"9a803fcaec81414e","fromNode":"38d3d1a313c094ee","fromSide":"right","toNode":"8ec17237cebe7433","toSide":"left"}, + {"id":"7ff52c30a0b0347d","fromNode":"a729b7930412f0b1","fromSide":"bottom","toNode":"d405163cb9ecd804","toSide":"top"}, + {"id":"d97ef554530b15b5","fromNode":"c20eeff7484d8a39","fromSide":"right","toNode":"a729b7930412f0b1","toSide":"left"}, + {"id":"034d145edd7cfce0","fromNode":"0c8534c8ba68c9a6","fromSide":"bottom","toNode":"6094c53caf966263","toSide":"top"}, + {"id":"da18b7fa4859fa6f","fromNode":"5eaa425c204bf600","fromSide":"bottom","toNode":"6094c53caf966263","toSide":"top"}, + {"id":"5d5f4fef281a656e","fromNode":"6094c53caf966263","fromSide":"right","toNode":"da500b2b12ed0901","toSide":"left"}, + {"id":"5573fa12a3a02ee0","fromNode":"da500b2b12ed0901","fromSide":"right","toNode":"20ce8d75f0f35588","toSide":"left"}, + {"id":"c4828432b71fd99a","fromNode":"4bfacdf3ddedbdec","fromSide":"right","toNode":"ae48e80ccd92bffa","toSide":"left"}, + {"id":"8ded09c7902a30b6","fromNode":"ae48e80ccd92bffa","fromSide":"right","toNode":"ed5a265dc4b72aaa","toSide":"left"}, + {"id":"4818c7bc8aa99b57","fromNode":"b624e8c6302b9a1c","fromSide":"right","toNode":"1054909d642ce071","toSide":"left"}, + {"id":"d58b296db32dc932","fromNode":"1054909d642ce071","fromSide":"bottom","toNode":"1e1a1a0d67920443","toSide":"top"}, + {"id":"f88001eedfed69b8","fromNode":"1e1a1a0d67920443","fromSide":"bottom","toNode":"092cf6719d47d01d","toSide":"top"}, + {"id":"d0bfe0faa41e4e2f","fromNode":"6c3a6982a53e7df9","fromSide":"right","toNode":"f3c36900dd3ed9d1","toSide":"left"}, + {"id":"14130329273bf6fc","fromNode":"092cf6719d47d01d","fromSide":"right","toNode":"14a4450243ca9953","toSide":"left"}, + {"id":"4d588dd609ceeb1e","fromNode":"f65edb48b74e18d7","fromSide":"right","toNode":"cccd4482e817fca4","toSide":"left"}, + {"id":"2e2be072d2f0e10f","fromNode":"e0d016f4bb106554","fromSide":"right","toNode":"722e4b9c310e6d2a","toSide":"left"}, + {"id":"8c75af2dfe500f7c","fromNode":"f65edb48b74e18d7","fromSide":"left","toNode":"e0d016f4bb106554","toSide":"left"}, + {"id":"ffb790d799b2ad82","fromNode":"f65edb48b74e18d7","fromSide":"left","toNode":"a9889437875a9263","toSide":"left"}, + {"id":"cdc9289e799ecaaf","fromNode":"a9889437875a9263","fromSide":"right","toNode":"50e241bef2144ea1","toSide":"left"}, + {"id":"7f1bc02337b44a20","fromNode":"36c9ab3fd7a0a402","fromSide":"right","toNode":"a20bd9b934093730","toSide":"left"}, + {"id":"8785ed74e88adf4e","fromNode":"6454ea0b5f37aafa","fromSide":"right","toNode":"da8b0f86919e99d9","toSide":"left"}, + {"id":"7ed2af81de878d33","fromNode":"ab5c75b7401fb031","fromSide":"right","toNode":"da00f9548457388f","toSide":"left"}, + {"id":"b9462798dc7ea087","fromNode":"ab5c75b7401fb031","fromSide":"left","toNode":"36c9ab3fd7a0a402","toSide":"left"}, + {"id":"6e6a4a6a3c31137f","fromNode":"ab5c75b7401fb031","fromSide":"left","toNode":"6454ea0b5f37aafa","toSide":"left"}, + {"id":"c23bb251830336d5","fromNode":"b5bee6a3e7c29d31","fromSide":"right","toNode":"f65edb48b74e18d7","toSide":"left"}, + {"id":"9ab29f4b57e27b0d","fromNode":"b5bee6a3e7c29d31","fromSide":"right","toNode":"ab5c75b7401fb031","toSide":"left"}, + {"id":"f54ee3299cbf7265","fromNode":"b5bee6a3e7c29d31","fromSide":"right","toNode":"dcd9236bd7c84bd4","toSide":"left"}, + {"id":"61aa378205c46b26","fromNode":"dcd9236bd7c84bd4","fromSide":"left","toNode":"ebc5c6d7451acc3b","toSide":"left"}, + {"id":"28f6e87b0c7eea26","fromNode":"dcd9236bd7c84bd4","fromSide":"left","toNode":"a49465d6a6a3c3c2","toSide":"left"}, + {"id":"ff4d8f82fdfdb90d","fromNode":"dcd9236bd7c84bd4","fromSide":"left","toNode":"987e81ef1f1995b3","toSide":"left"}, + {"id":"92f9ed21804f53e2","fromNode":"987e81ef1f1995b3","fromSide":"bottom","toNode":"11e198e842aadec4","toSide":"top"}, + {"id":"b3ec4450d2d0a73b","fromNode":"11e198e842aadec4","fromSide":"top","toNode":"7f6f9185b340d930","toSide":"top"}, + {"id":"dffde18030232f37","fromNode":"7f6f9185b340d930","fromSide":"bottom","toNode":"5a48574ff6eeda7e","toSide":"top"}, + {"id":"257676f063ba93a2","fromNode":"ebc5c6d7451acc3b","fromSide":"right","toNode":"c29809ca3c70881b","toSide":"left"}, + {"id":"a19f6c3e9df6f3c6","fromNode":"a49465d6a6a3c3c2","fromSide":"right","toNode":"c29809ca3c70881b","toSide":"left"}, + {"id":"9b20ae7ad0081184","fromNode":"987e81ef1f1995b3","fromSide":"right","toNode":"c29809ca3c70881b","toSide":"left"}, + {"id":"f093013ff0a96dd0","fromNode":"11e198e842aadec4","fromSide":"right","toNode":"253044dc6cebe206","toSide":"left"}, + {"id":"02244e836b50d487","fromNode":"7f6f9185b340d930","fromSide":"right","toNode":"253044dc6cebe206","toSide":"left"}, + {"id":"99cf66af0f6ec6d3","fromNode":"5a48574ff6eeda7e","fromSide":"right","toNode":"253044dc6cebe206","toSide":"left"}, + {"id":"3f71b0b7e384a8be","fromNode":"b5bee6a3e7c29d31","fromSide":"right","toNode":"2ee598faf0603188","toSide":"left"}, + {"id":"56f5f551d20be422","fromNode":"2ee598faf0603188","fromSide":"left","toNode":"c477cd2a76cd46fb","toSide":"left"}, + {"id":"cc3407d414603eb8","fromNode":"2ee598faf0603188","fromSide":"right","toNode":"c4978e46cf739ba4","toSide":"left"}, + {"id":"b6160496e46a4eae","fromNode":"c477cd2a76cd46fb","fromSide":"right","toNode":"c4978e46cf739ba4","toSide":"left"}, + {"id":"3368bcd74ba9e4fb","fromNode":"9005abbfdd8f3246","fromSide":"bottom","toNode":"8944328366cdad0c","toSide":"top"}, + {"id":"6909067532cb91bc","fromNode":"a96110788e264552","fromSide":"bottom","toNode":"6f03c475fcf16a01","toSide":"top"}, + {"id":"321843e8dd3be858","fromNode":"5b82d2f5eb26eefc","fromSide":"left","toNode":"5d4daed7f83a3fa5","toSide":"right"}, + {"id":"3925cae98ff11bdc","fromNode":"9a824939bad661d2","fromSide":"left","toNode":"d89b6477389b9a45","toSide":"right"}, + {"id":"88b616e16f0fd305","fromNode":"f1cd43613a1fdfa5","fromSide":"right","toNode":"5b82d2f5eb26eefc","toSide":"right"}, + {"id":"68f5cf5a18a17801","fromNode":"f1cd43613a1fdfa5","fromSide":"right","toNode":"9a824939bad661d2","toSide":"right"}, + {"id":"ebac050a172817ba","fromNode":"f1cd43613a1fdfa5","fromSide":"right","toNode":"8fa04043b651b57e","toSide":"right"}, + {"id":"c6940f9a6f6ed020","fromNode":"9005abbfdd8f3246","fromSide":"left","toNode":"44300ab8ae0139cc","toSide":"right"}, + {"id":"90f4d6c4e8f93b32","fromNode":"8944328366cdad0c","fromSide":"left","toNode":"0bc6d2d448f012fd","toSide":"right"}, + {"id":"9854bbe1c5c3932e","fromNode":"a96110788e264552","fromSide":"left","toNode":"5047212eb42c9e69","toSide":"right"}, + {"id":"16d9a0e220097480","fromNode":"6f03c475fcf16a01","fromSide":"left","toNode":"f5ccbef2e5e250b9","toSide":"right"}, + {"id":"d52e7f0275237844","fromNode":"34fed438f96dfa4c","fromSide":"right","toNode":"9005abbfdd8f3246","toSide":"right"}, + {"id":"63ad29914f63862d","fromNode":"34fed438f96dfa4c","fromSide":"right","toNode":"a96110788e264552","toSide":"right"}, + {"id":"c58c7b2bd323e581","fromNode":"b5bee6a3e7c29d31","fromSide":"left","toNode":"f1cd43613a1fdfa5","toSide":"right"}, + {"id":"b427c81d66172385","fromNode":"b5bee6a3e7c29d31","fromSide":"left","toNode":"34fed438f96dfa4c","toSide":"right"}, + {"id":"eaf4a6506bae5f72","fromNode":"b5bee6a3e7c29d31","fromSide":"left","toNode":"204d6c2f3ec03ac0","toSide":"right"}, + {"id":"ed232ba50bf6c970","fromNode":"1684e3f8b6f17829","fromSide":"left","toNode":"b1dddd3ed142c348","toSide":"right"}, + {"id":"a0f82a31cbffe766","fromNode":"204d6c2f3ec03ac0","fromSide":"left","toNode":"d1cb8d99b00c07c8","toSide":"right"}, + {"id":"0f934757be6b10ed","fromNode":"204d6c2f3ec03ac0","fromSide":"right","toNode":"1684e3f8b6f17829","toSide":"right"}, + {"id":"eb49e3a35fec607d","fromNode":"204d6c2f3ec03ac0","fromSide":"right","toNode":"169bd99d304f6f85","toSide":"right"}, + {"id":"4165dc7658a3b437","fromNode":"169bd99d304f6f85","fromSide":"left","toNode":"c328cec51da1530b","toSide":"right"}, + {"id":"711a31af774553f9","fromNode":"43c52f1d3f4f4337","fromSide":"left","toNode":"cd865939df274ef7","toSide":"right"}, + {"id":"55cbfdf0e50ce7f1","fromNode":"b5bee6a3e7c29d31","fromSide":"left","toNode":"43c52f1d3f4f4337","toSide":"right"} + ] +} \ No newline at end of file diff --git a/多体+耦合求解器/风机模型及augmat_matrix.excalidraw.md b/多体+耦合求解器/风机模型及augmat_matrix.excalidraw.md index 378c429..b072b71 100644 --- a/多体+耦合求解器/风机模型及augmat_matrix.excalidraw.md +++ b/多体+耦合求解器/风机模型及augmat_matrix.excalidraw.md @@ -3371,558 +3371,1054 @@ mMrgDxmY/7Bm4whyTqGw96pIFF5KyJr5LFpYFXmldaGgyFvH69t4W8nFyGdI4ujZHSGUva034jU7V6nd Suko1ZvjEAY7mqmhbG8MYRvrakyPjp8SwMgDrYDFHSPMiHIjQPIlglyclueLkZmthmsineJnAikDe67ikd8oDf4dpk3GnYJm+ZnZ+nrtGALT2RgR3AnZGxyIKrDu7gThnGHBCsSjelKiRza6c3bH47/m4YwKb5HFbru+kQaIGwEmZnmxnhxGL6Tv6rr4Jv8h5+IQki8AyBKD+mBSykXHrMKA2+Db+j6WxOe4A7SjaBcIAngQx+g3fA4h5+O5ezDf -hnzBnnxmLBnpWkWOlRmlp4hlPLHRoa5H7fxmjBtFLScBE4zHkBoPGeqFC2qeZRJD4qFJhDDm+52bpZuH/xlQA6czDUnGAWktQ7yqFf25aSbjL7tu7Tm6kyyyu5oKmabJiQA2cCnO5jiR3FBkorU9T/4xKkEVhKW4B/pCTaFysjuqiFZl8nHwYzoGp5DjXzw/aSp6a2uI8AS2+BzkJ/+nWqCI8kuw7Nqki8k4/EhUltxAa4ik5oywmolLMGnVm6n8 +hnzBnnxmLBnpWkWOlRmlp4hlPLHRoa5H7fxmjBtFLScCavGeqFC2qeZRJD4qFJhDDm+52bpZuH/xlQA6czDUnGAWktQ7yqFf25aSbjL7tu7Tm6kyyyu5oKmF9p+ACrEYzs5woDOOpK8yM9AmJBysjuqiFZl8nHwYzoGp5DjXzw/aSp6a2uI8AS2+BzkJ/+nWqCI8kuw7Nqki8k4/EhUltxAa4ik5oywmolLMGnVm6n8a9fKGnGvZnGXHoxlWGKOQ -a9fJP6ivZlmPHvZnGXHoxlWGKOQ4huEZ9i5Q63UFySmJBlSEI/MlLnwsG7w65gg6BWRBGkzXFaalTOG1wAWKmau7DslzhI25Qh+Ej+7iW4xUa7k4pZlnHFX8gI5mpg5a5mK5kvQAo5lkqqXOgueB22wncjZ/Tr8qbETLXZDcIBCEHnBjkJE5noeg1davQh7ZnX4EPRLzjI6v6KUymRkz6nuImlOmuGBrzSHhp5mIFWjHwFZ17gBY8VI85lPCBvZm +4huEZ9i5Q63UFySmJBlSEI/MlLnwsG7w65gg6BWRBGkzXFaalTOG1wAWKmau7DslzhI25Qh+Ej+7iW4xUa7k4pZlnHHlxaXOgueB22wncjZ/Tr8qbETLXZDcIBCEHnBjkLY5noeg1davQh7ZnX4EPRLzjI6v6KUymRkz6nuImlOmuGBrzSHhp5mIFWjHwFZ17gBY8VKs5mS5A4eRtMndL6BSl1Q4ahkdOlJsG/qkjDbcWlJO6wzG1Tyyu5XuxLtb -S5A4eRtMndL6BSl1Q4ahkdOlJsG/qkjDbcWlJO6wzG1Tyyu5XuxLtb/+4c3a4A6BQ4wg6BQ6rh5Yj7ezp3OxerBCkBEwAW5lOqgMARDFgGWJZBAOkCDfx/HjoLChcI96plqle7A+65LBRY9TLC6HiDCyC2ZSXkCC4lnepjRkmOC65knWadk4NwmSpn4cn/hlrJnp3FZ7R5vrCWhfOktYglS4RKSx5mqkDx5lGyaem5lE5IkLg5leRKiZYoLjh+Ht +/+4c3a4A6BQ4wg6BQ6rh5Yj7ezpHyqHa6SUAGWJZBAOkCDfx/HjoLChcI96plqle7A+65LBRY9TLC6HiDCyC2ZSXkCC4lnepjRkmOAq5knWadk4NwmSpn4cn/hlrJnp3FZ7R5vrCWhfOktYglS4RKS+5lGyaem5lE5IkKg5leRKiZYoLjh+Ht9JApbQu4vH5N5mePb0coL5mSW74lKyu5bXwS5nPcG8BlOqbQ5n7bwQ5kPHKnymlhkStEhsjfgQI -9JApbQu4vH6T5mePb0cqX5mSW74lKyu5bXxm5neDSj25Oqaw5n7bxQ5kPHKnymlhlDcxiQCzO6wCDIU6I+D15krRohsjfgQIErUjxJ8AgOgJ2BGOy3wBfCljtE7dRu5m9wjdIA6xRQOATwwMvA18BFlLChnYZii2n+xni2nz5mS2mwPGWnR/ahXmj9XQAvzMYRqZS/tCb5m1qDb5lwei3nFEDG75aX64aFHn5lKRbbeJve7MFm9+m5ck9rpiQDJp +ErUjxJ8AgOgJ2BGOy3wBfCljtE7dRm5m9wjdIA6xRQOATwwMvA18BFlLChnYZii2n+xni2kd5mS2mwPGWnR/ahXmj9XQAvzMYRqZS/tBD5lwei3nFEDG75aX64aFFz5lKRbbeJve6IFm9+m5cmL0GUATCUBU0Tqna0iLPMhNwqaCo0wyPnR0yq+9pZEkRpDtRjYqg6xSr4C/pA7RjC2QymmKoLNxkKOEMZmVMmoKFO8jP8Ae5k++EmTxl1G/pAIk -YSGlpplTsBkorCUBU0Tqna0iLPMhNwqaCo0wyPnR0yq+9pZEkRpDtRjYqg6xSr4C/pA7RjC2QymmKoLNxkKOEMZmVMmoKFO8jP8AR5k++EmTxl1G/pAIkAvZlx5l85kJ5n47z9wn9NGKula4bKumGJHPmnB0ayzHR0FYFIQ9GLqFHqFHRmpqlZTYiyEZxlma4iJz/aGa64RW5dHFTqyl4zV5ngQBZfBOwCAFmuYjrYDfxy3K5PxD0SCvXS10zhDi +AvZl+5n47z9wn9NGKula4bKumGJHPmnB0ayzHR0FYFIQ9GLqFHqFHRmpqlZTYiyEZxlma4iJz/aGa64RW5dHFTqyl4ztIql6A/9CkzzPxBDcK6IjTOb2xiXchW5S+9pjS5xXHm5l45muUKCUkFiDXMFQKZmkGSUh0Fnqolbwx9wyne6aJhlqqqvqc2EJ/ANw4QFkjKHKLEhaku+7SlHfxnxBlW9Sn+lqLp527khJc7EsampunOUEjT6oLEzXKTO7 -UyRfNBduk8hmZhhxXHu5mk5muUKCUkFiDXMFQKZmkGSUiqFnqolbwx9wyne6aJhlqqqvqc2EJ/ANw4UFnVSn85lHbB8bwr+nLjp6hkUDEQB6XRlqLp527khJc7EsampunOUEjT6oLEzXKTO7b+nOUGKamag78ra2hlGZldoH8QHjFkwl5o+FerAvIDJ9RhFl4CGMOQn1TjYAqS63yDngxogBIBDTYCL5bYwlmoAtIxeog7FyvlS7Zkp0SKFmHZnd +b+nOUGKamag78ra2hlGZldoH8QHpFkwl58ykLJyMOQn1TjYAqS63yDngxogBIBDTYCL5bYwlmoAtIxeog7FyvlS7Zkp0RUFmHZndIHJWkRtAPOlD146HE/5ksRlTul59FbsycnD6aF2+kxAlsBgdHjeFnXHiHJlB5n/m6/cEsm4FnI4HZV6neg6PcaeJKF9rH+KNsIvhhwbw0iqWWgfgTOtD4CpV3yKv6k6C2+D+zwO+AuWT+Wg15lwpAtpmw5Gg -IHJWkRtAPOlD146HE4FksRlTul59FbsycnD6aF2+kxAlsBgdHhVFkmyk1FldLEwRlxNKPZGqLavw4FnI4HZV6neg6PcaeJLw5ngQA4dFdHHzFnJcDH+KNsIvhhwbw0iqWWgfgTOtD4CpV3yKv6k6C2+D+zwO+AuWT+WjD5lwpAtpmw5GgxnfDzpv61Zn4mnhmk4Jk0umhsmaHRSqjvYir5nDxDwKKnBTPZnpby85nmgk1FnPv6eQGYlop+EWcrcW +xnfDzpv61Zn4mnhmk4Jk0umhsmaHRSqjvYh95nDxDwKKnBTPZlLyls5kM1K7SkbSbx+GMpnhurfFmWirIU5VOIsG4HAbmA62JbjwFjP7Au4pazTNF/FkznzWQ7L5kPWZOPJcclwlkbk6qum7gwFxxqgA8UJVDCmIg/9CsGxLZZfgBuaDJ8k6Rn8jBmFkP5kW5l3a62uJTRTrSQ4DIOsiRGnT6l6cnKKFz6ku5kLfHgkDF7CgqiMQQgFk23QpMYuP -4kaIKSkQu4HAbmA62JbjwFjP7Au4pazTNHx+F5vb/w435kPWZOPJccmSlkbk7yilerDp64wKKP5m8Fl39AFxxqgA8UJVDCmIg/9CsGxLZZfgBuaDJ8k6Rn8jCpFkIFke5l3a62uJTRTrSQ4DIOsiRGnT6l6cnKKFz6kh5kLfHgkDF7CgqiMQQkFk23QpMYuPBvFlFRk1FkguRfFmVmJLckKBzqQ6O+Ey26A1Ap+H0hQsqaglkKT6BejKln6mAFlz +BDFmInAsWlr/5LckKBzqQ6O+Ey26A1Ap+H0hQsqaF9oXqBcoCrAQw1J5KwDfzBHzouptCRsoCJEDasGIOHiSj35n3EaklksbAE5kSdhmQxT1Hg0DgJwSW7O8YOFlQIl24yY8SoP7gtB0wCdfaKP4r4zEqhDFlMZEuRlH+kJ8H0h7rGZl24g3zUBnQlkoaoug7zWa86F0hKXBbDHHw5DR+EJGkIClReErEJw65IS585n8EEyB4p+HTOkelns7wAsn -42yrAQw1J5KwDfzBHzouptCRsoCJEDasGIOHiSjwFn3EamlksbDk5kSdhmQxT1Hg0DgJwSW7O8b5FlQIl24yY8SoP7gtB0wCdfaKP4r4zEqjelnwVif2aqXBMZEuRlH+kJ8H0h7rGZl24g3zUBlilnfunjalbAZiKlQ5bJsZFKmDPLR+EJGkIClReErEJw65IS7i5n8EEyB4clmiB7bWZSlnSpYAsnJCIRkHrHELu66skJulfn6og5lll65mOMYJ +JCIRkHrHELu66skJulfn6og4Glmq5mOMYJsEZlnN5llZQLu5ClnXqkJumVWwjO6GB4b5nLgz0G4Ztwl645lmL5mBBlEBnVlkr5nJFJ8anilnRB7READbZX1pDKSRDi4IzxkRUyC4IA67HYwnJaCVFmkFkV5mdCHGHAqYiWsjWFnAvAzXp1slEyZ3YIMOliYl0ZEDBJWNFnfp32DCpAo+jslnkv7rth6qB2ln4EFVikqQYuOk0hE1ykL4pIRJasbH -sFHllT5llZQLu4hlnXqkJumVWwjO6GB6xllAkr0G4Ztwl65nllX5mBBlEBmvlm35nJFJ8amRln1bpiQCdhIj2IPlmQlkvYz+UFeSwglBDKSRDi4IzxkRUyC4IA67HYwnJaC7FkyFn95mdCHGHAqYiWshZFnAvAzXp1slEyZ3YIMOliYl0ZEDBJWNFnfp32DCpAo+julnkv7rth6qAtlkZjhtlkvUZ1SmQJ4jO4POZN8nwmZIRJasasVmGP5AcGH3 +lmGP5AcHkkqlPzXEkUwz3tzJ9w8Kj4ZBLZxetK+JYIFqcIBHFm7Fm3/qr86K1BW5n1Fk3I6Bh5cyRQplBJnt5kdFldenEckdZCdpKXfr2l630J1fBboBcFlvFk8Fk5I4/9x7A7CUERQ5/7HX+mqrHJ/y96hPjzkPx+KDHqCwIAERzq+CwTbPlmBIDElkalkWFkUFn7Zk25k8sbTllBqxPplT2n0lkMKl6MSZWnFrTK5gJbBPMn9JElph2lkQMlTk -BiQCjhL1LDAVmbqClPzXEkUwz3tzJ9w8Kj4ZBLZxetK+JYIFqcIC4lkYlm3/qr86K1Be5nHFk3I6Bh5cyRQplBJlz5k3FldenEckdZCdpKXfr2l630J1fBboCGFmMlnGFnMlmmFk5I4/9x7A7CUERQ5/7HX+l43herCbA5odER6B8VlphAlwREyDumASYwOND+KB3sChvRsvqPhgemmbelKsS5lkk5kuWRfOBHFlqTBKFlqZ7YVlBqxPplT2n2lk +6hB5BtGTkGE77Xul8VkasnyR7YdEdJnq5nN6mHGYvsDSuLeOKSABPOws1G1FG8dxDjAtvDjZ4IJmZhjEVm45lP5nV5mTlwRRhv5kKh4mGng0AtFlMiHnZkBxkW+lTukbWm8DypaAPxpslnP77k9priA1qJDFnY1zOOnEhn/alSwpDGlnKq+6lcVapQ6ZqmH5lEJ76CTKlnZXQ/8jwDIqO4RgDVRyshKEKmIOHBzyqVlyrwuWTvXB1FlqTDUFkJHw -MKl6MSZWnFrTK5gJbBPMn9JElpjUVnQMS0Vn97BJAm0Fl+HKe6k+na9w5IqkaslTqkug7yR7YdEdJkG5nN6n2Vlgln4sANeQuVm+xAvsDSuLeOKSABPOws1G1FG8dxDjAtvDjZ4IJkpFkiMR5lmk5kD2DmlnPcCWlnGGl3OnZSJ5bFnZm/hk+ZkW+lTukbWm8DypaAPxpulnP77k9priA1qKZVlUFk+JhedpAqHjO49w7OUHMm6+6lcVapQ6Zqlf +9d5ginLWnf5kdelAVmneko2k80As8bZ3AuRHRWaLFBPAB2Vl2tEvr6WhmV+nHRksq4Wh6PSHDNFnRnLXLhrFmV4Ld4WrT+g5WtJJh5eVEaZmkhnDamoHYJlFxrHDvTTkGdVkaskpamZzGc/y4aiDzy4whXgDFyIzMQBeBFJikzw/tJdylFZkqVkiMQkVn7FnW7AT1CE5m6lnLCZUVna5q5tGMRlt5kvpmAOmNeAm4j2DpgIgXkGtak6LLO/JgghD -5lMSxiQDp66Q7INVm9MYU0TgYTZXQ/8jwDIqO4RgDVRyshKEKmIOHBzzGlkDVkuWTvXDhVkHZkL/xlqoCMFYFnnZkBxmzVldeko2k80As8bZ3AuRHRWaLFBPAAbVkmFlGyYWUBJpkWrKhB7v6IMakfr4sm6PSHDNFnRnLXLhrFmV4Ld4WrT+g5WtJJh5eVEaZmkhnDamoHYJlFxrHDvTTkHU1kaskpamZzGpBDcVmWg4AjhXVmsoC4aiDzy4whXg +Flj64Olmh5lENH2qLbg5ulkaH5ovYO6lgtEMxkqo57lk0hIPSm9L6Pgb8BklYERkHo9HeZHB7Jq4CRlC4fJLgiwIAQ1rXIiLmIsliQ9yupkHGniXgRVmP5kfllY5mUFmxVkNFkmyG6Vld4pso7laFYJlXFkNZlfMRAEyrBkxFT78lvsa1FbJ/ovUCnVlsDaWZ6hQ4DEb8lmQhYve4DZFiVl5UbOwqrqRIBC8oCoEprEQXGDyXSIKTSoAemlEKmJG -DFyIzMQBeBFJikzw/tJdylFZl9VmNugmlmk5l6siFlkj5l4lka6m5FlYv5so7laFYJmklkNZlfMQm4j2DpgIgXkGtak6LLO/Jgghw1lmVlGyZj66dlnp5lENH2qLbg79lkaH5ovYO6lgtEMxkqo4qQZjlkSR5XSZJ4GSpYgsklYERkHo9HeZG9jBiQAoRLztCs1mBqJhqTZRJPiw+VkQ1rXIiLmIsliQ9yupkHGniXgfVkhVnyVmE5kKFkRVknFk +IkFnl5k/L63PIaVlLVl15l254N5n7DYOSmYJkZ+ldpm/5lkuBl4CJrL4BBlmJ3alyiLepTZUinVnoAmWPERbLuQ6TMKU4GKR7FKkItEkG5JMzU7qDslUxn7HGNbEhvb4hHxAZFiaJuLRB4qsjrqToCZbUAf/otsyZrg52Ds7L5OwkZkfGD0MDqllqVkflnPQZWFkMRSTlmZkBYcnKGLdhk7ZFUumwpmDkRVKGiPo6WBYeQxPr1fSqBShEinVll7G -myEmGm4mRjym2ukEVmSBJAEyrBkxFT78lvsa1FbJ/ovUA61lUon85l2JrmZppukpRFsFnPo4ve4DZHVVlG5ngQDp678Sn7wAhOYRSp4IC5cC8OAvjwlvjUjCTST/awumDkEn01DSFl95k/L63PJD5lhqiS1lm9ZWum2l505mKqnCknnzEJVll4CJrL4BBlmJ3alyiLepTZUj51m9smF1noAmWPERbLuQ6TMKU4GKR7FKkItEkG5JMzU7qDslUxn7 +7llqX6yFnkplzhKJek0akollZOy6oqCfBTFjX8ILdT5gmKQpnIjY1QQ1lEKkKORl5kV3i81m1Fnw1kHZkL/x+JmX/Kfd7w+kIMnnzH0VmoW6eRZwUikX7BsZmARVGKEn7rfFs5k1bGqjH4PYqL7oqkYOnZFk8UTOmBqAgbfR/yJOPosjAmhz8xyoyiQ9wc1mg2mdFLc1ll1k1FlfOAxVlV1kJTx6x4HmI0VkI+mupHxZbW4Ac5YoAi9NG5RmNvj9 -HGNbEhvb4hHxAZFiaJuJ/lngQDhjBe1k3CgqsjrqToCZbUAf/otsyZrg52Ds7L5OwkZkfGD0MDBVlyrxYlk/sCZFkMRSYVmZkBYcnKGLdhk7ZFUumwpmDkRVKGiPo6WBYeQxPr1fSqBShEgr1nWcmF1ll7FVinluluFnkplzhKJek0anylngQDqA515lZOy6oqCfBTFjX8ILdT5gmKQpnIjY1Rh1lEKkKOS95kV3j91mHFmx1m/VkRSR+JmX/Kfd +TQwVn9qk91l5ewJ1m/Xz8VFBBlr+lN+4quF/F431lH+lnUn3n6AqDv6Lasnv1lTsntSEKGk05DCUTneKZhCxKD9FhMHQ1EhP+wlhDkEmi5BL1nVFkuWRmVBr1kUVlSwFJRkmOCjukQxni1n1ZnGVnHVh7KJelYRaQQTDZVlU9xV3BT1CaIDcFlGybNGkFIYV+nUKFjFkdhr+OkeVrTqmcVFzGnF66VboycbcBnGFwHx5QelAXL525HXRCFnp7rNC -7w+kIMlT1nB5mrEQYzI5mIiHTWyikokg0DRyjtXCoNmoin85k1bGqjH4PYqL7oqkYOnTFngQCg+CBbTe1kkUjDzz3bRr6RfbzzWwfAB0gAbK7UwywTYMkkPYC91lMNkHFlhVmsNk+5m3On7ikZG6xVkI+mupHxZbW4Ac5YoAi9NG5RmNvj9TTGVnxeJMlkF1mmFmvcwwoH6alBBlr+lN+4quF/F78VHscnBraXAaV+nHRm/qIc6qrlnsFmw8ZerC +kCVHRKJVG7Xq4u+4hjbCz4/tKOsJ/zRkRBLZy5EDeQI0ww4fRMjqOZnhpCl1lQNkflnZkDklnPcCUlnzJmQ/iihmPOn/2kShnbVmbhDVvDtJE3/qTWZVX5Mja6mgAJTd1k8FntYGq1k0nLFIZvSnBDEQBFD0GXtIJFlEBmTD60BFg2FQrEXort+7Exn0H7RHHD1kIzZGKT1WACGKuZA/NhtADslia+A+gx4woMkmyNlf7A81kr1nisQv5laVm/3F -Wg5RNl+CCqNnpCAe5HneKZhCxKD9FhMHQ1EhP+wlhDkEmi5DGNn7FkuWRmVA/VkWNlSwFJRkmOCjukQxkZ+ldpm4FlkuB7KJelYRaQQTBQ1lU9xV3BT1CaIBGFlb5nw1kflG19YTpkvcJgUEDEaI4Fka4ee4eVrTqmcVFzGnF66VboycbcBnGFwHx5QelAXL525HXTWFnp7rNCkCVHRKJVG7Xq4u+4hjY31kBukYzzWSpMCDJNlDC5YWI+QI+rTS +/zoseY/ynjykzRlY1mEonUyYX+hHxFy6YiqyTBS6cKENnKGgFVlX1kdB6PNbujrsVEZumlNmOVlvBaXqneDQiRkXRmOVl1FrVNkasnSrFkhn45Hk2nuenIZmTsmOVlJFnPP6hun0H4DT7i5b+ukq4HJ2kXV7S7HvEZ1Nluyl1ZEHsJdVmPelY96t9bhFEpRE51YKJpzK5nqB9KTQNyMATrOBSnRAiSzjDhdDHcgirKolCvlkApiT8mjlm9OSNtA+ -x45EC53Tbmgl6ATMp0Nmg2l44KIVl91mmNnisQoFkRRhoFkoF6EJKihmPOn/2kShmAOmNeDVvDtJE3/qTWZVX5Mja6mgAJQFXyeNmr1neNmsAH1SnyNnzpkWJnHOGRFGPZoGhkUDGTD60BFg2FQrEXort+7Exn0H7RHGKNksSktMCQTQHNl+mAXIgPOgGMTGkq93ZOqC8OC2BKrErXNl6aSxZx3NkmNmhVmPNmTlzPNm/3F/zoseY/ynjykzRnK1 +1n5Mr8FHeZkXxmXZlABg3ELg4FQiobRnYn4PZnUO7oEx5NlucSAUE4jFr/5s3TWVor+lU+nGKwJqHVjpfwqEqxRhLsk6L2zlvAGAD0GwtumRrAirJ2VCQNlkFme1nO7DjlmnNmCLE1rEp6kBsltFkpVkhJnXNkxLHOUT2PDTJQmVZk6ACqFlmIvNlA7JJpkN2Yu+65hzwg7WgoJ5kmgyCukCumtt73BlFpllIFTGE9NKJrDcGTJ8AbKwRQRKUAM9 -mEonUyYX+hHxFy6YiqyTBS6cIdNmUFldNmWjZqlgYD6fw48FkGJFnOHsVEZumytnEhk767b6bj+mb7IiRkXRkKtl1FpP5kasnSrFkhn45Hk2nuenIZmTskKtlDFnPP6hun0H4DT7i5b+ukq4HJ2kXV7S7HvEbqtluyl1ZEHsI01mPelY96t9bhFGl1lfxm4qHrcnKkDnVndsCXVk3Ciy4y1vCa8zLzKm+Q5hDbLQHUB09BBmLaRn0gxj7QyVkApi +Au1lEKkxNAwtnDlkH6SHpHHNkaZi1HiqNmmGlf5mGVntFkYtlY1kHZHOURoHDlnY7WkFJDVnhH3hEtnCiwO0brOEXcbvw4L+6vmlZJnzdGTHq4NqGemElaqmETHF2z76JE9JloFleiAY3ywBAAYRSoB7chsSiAazNbqCRKzYBa+ns8m4JI7FkHNmP2TUWBflkI1kL/yNcS9N4yOFo1koNkY1loNlCdijsh8XrpOBjbD2yFkyJYGbWUBDFmt+KVG6 -T8moVm9OSNtDANn5Mr8FHeZkXxmXZlABg3ELg4FQiobRnYn4PZnUO7oEzCtnVFmmFnlQi7SkKAFBfb1FmzYGBBAJqF11we1lGKChFnSEpfwqEqxRhLsk6L2zlvAGAD0GwtumRrAirJ2VAFNmyFnyVnXuRANldf5jhw5cEp6kBslXFkdemaVlCdieSwPupGqi2jhaJmUrqwUg0mDuNnyopgtloNmltkVUmvoEu+65hzwg7WgpF5kmgyCukCumtt73 +uRkfHJVG6Jtm31lJmF4GzbR5ECmzYET0Eh5lMxn4YaV074JEbd6C+kutEDg4UG5RL5i2Egh76SFMm7BFkFumTFmL57xT4m25bum1tlc+lYpmqdH+XQ5640hlZFFNtnosGrqk8zqCzbKPp/uxq15nN78ZbPlAzu4Dg7AWHxT5otELhmhlwGa6Q8n6VJVG4ClkzoHvub/2FkLHB8np1mjXhe/hx1DQmxLpTQmxEfKrEby4Dsk5MGykyGYZq5FAbZnw -BlFplnVlglkjxky7Hm5lCAJTGE9NKJrDcGTJ8AbKwRQRKUAM9Df1lEKkxND9tnIVkH6SHpFJtkaZi1HjzJmJyFginLWnYFlTtkhJlZtkHZHOURoHDlnY7WkFJDVnhH3jFtnvFmltlGWmYNnoWx3MbzjyHVn9MGCrEwqEp57IBFm/7McHlJn6JG0cHMhHx87G5lGKD1VlAOjU0TI6ABuCCMxtwxPIw6pGCRKzYBa+ns8m4JLolnxtmP2TUWCKVlx1 +pC85iHNkcjDe1ldf42U7qGSKJm/ymQIn/yk/PJA/BYT6cLzLjiM5kv5qaBp2bCxtmzJRX1mBgZg8lnvFLpAsh6OVlCjFbmkK5nLXIhg5ahmWQ6zqqWQ6w8mjJBuRlX0Cy/K1wAPRmpZnkkqiVT38iz0KFQCtWAHFFj3jaIg/9CHM7kppfUDoGqL2SOJB8AQLoDRVmV1lwNlsHarVmk0nGlkPtnX3Iqx5VfRehgw1jgVnqEg6hIjBJSTSmNmOsS5h -l/VkveLvrFWBlyxkZtkRmkwNnI5HBpopQCiU72yFkyJYGbWUASNkTaz85mt+KVG6uRkfHJVG6Kdn+NlJmF4GzbR5ECnVtmoaZp5lMxn4YaV074JEbd6C+kutEDg4UG5RL5i2Egh76SFMm5W9Rl27EvaL57xT4m25bum2dlc+lYpmqdH+XQ5640hlZFFOdnosGrqk8zqCzbKPp/uxq15nN78ZbPlAzu4Dg7AWHxT5otELhmhlwGa6Q8n6VJVG5Blk +i2ZHDGnoPZEgaONw3j4q47vw4I66dCkZ+HLi4/RGOG4asnzW5BFnBaGErS/74IiFocrXXrRbTZhyA5k6jEQzaachp8rFCksBm2MbnmmyHZYMHDbE01m8MYHvRebotsxZrBKGDdoA1FL0Uhdswo8yRPLqjJ1R55TzNW7SGRtDCyBDDcY2bggxkw+k4ckbVnPpnT2npRk7VmARl7wyoBzOoGQqLORDeWgN3yvFnn1l+5kUboktnEDF8B7jHHQZm1UE -zoHvub/2FkLHB8kENkotmy5yhYQHNle/hx1DQmxLpTQmxEfKrEby4Dsk5MGykyGYZq5FAbZnwpC85gJtkcjDDtn/tnwn5lDjhKkHim/ymQIn/yk/PJA/BYT6cLzLjgc5kv5qaBp2bDSdmsZiydmzJQodmDT5lRk7Kk2d6QukKtlCjFbmma5nLXIhg5ahmWQ6zqqWQ6w8mjJBuRlX0Cy/K1wAPRmpZlcVlglkx0DM4QHNmiVT38iz0KFQCtWAHFFj +HynIcL1Ik02Y7hTvX6SCm1ikRL6F2JlBkcQHmCFdwG+jH+VGhH7i3wO+aAITSTBwIB0AQXUIELD7ODrogZhBG+L4dmr4BD5aphikdKdCEQkBjlkb3iqrAVZmNmkkylaWmBtk/6lStlZSSIMDYGJDlqLlz3xkvupsPL1Zjn+QvNlpKCXGHJqmCdkDhCGQY9A6zxnBgF2G4nqI60GjALRW5M5IcUHooHRB6RcJqCS41AwgC5BBrzTUjzlRpuQL41DK -3jaIg/9CHM7kppfUDoGqL2SOJB8AQLoDfVnmNmRVlsHbRVkEPKVlktdnX3Iqx5VfRehgw1h6VnqEg6hIjBJSTSgtmmVleNmOsS5hi2ZHDGnoPZEgaONw3j4q47vw4I66dCkZ+HLi4/RGOG4asnzW7xBmFLE3A7J4HnmmyHYlIp5eq2ylt2bA5k6jEQzaachp8rFCksBm2MbY9nCxZzdGnEmCcl4gwI5nvICU9maYAHNkHvRebotsxZrBKGDdoA1F +tF8nFnPJ2dlbZl8EjnpQMWC2uKvrC38HYxHveHqNmtFnihlpRk9+FS1mn7HVnp93DytlgnGtdppfH6e7eFm/BQ5Tqoky9bFKzGbYFczGOcmokx+wEBumaNHa655/aw9k0H5wqkODEPe6/Ml1inpdkwx4Jal2f4flq1ForybYhJAB7zFrKw78EEatbIOK3yGprGoVmPEFXIhhADsGSmtBHgBl7o/JB/DS+pC0iKRPKKNkJnK/cgiNrSGQHTCG7CX7 -L0Uhdswo8yRPLqjJ1R55TzNW7SGRtDCyBDDcY2bggxkw+k4cmMRmz5kvpnfNmbhAHOBSzz8+TOoGQqLORDeWgN3wMlkeNnA9ngtmg9mBw5lE79Ck8yngqawZHWqKwQaA9E7hTvX6SCm1ikRL6F2JlBkcQHmCFdwG+jH+VGhH7i3xRlk8vDccluLAHNkFwRCgDRFAt6iZ/J4WCGnr9MaYUqYTRs8mGHpXdlD5aphikdKdCEQkBoVkb3iqrAVZmNmk +oCJ66x7PLE0dkqJlozLFhAtMHevJy1lQCS2zb7oSpiBhdmiEmvZlqph1SlJD7LA4D+nzhkLOFYG596wI65JMwI64xuLDNHiH6jskptnL+nOUHlioZqmf1mOVl+0aT+mZTbUfooBk2PY1NmC4Jl25NBlEBk8nwEBnsjS9w7dVl1Nm4Z78H6oFmZRHJcAc6yvayGw6Qkh4QB+KAJEArFwzs4KAjLPEi9oYmlSfGs9mNnoH6S/7AaVl3dnc9kyXj0yH -kylaWnVNn1Zkg1kztlsRkwQ6COQ7ILRAm3VhsPL1Zjn+QIdk+lkJ5lpKCXGHJqmw9kDhCGQY9A6zxnBgF2G4nqI60GjALRW5M5IcUHooHbNmTFoMSkAFk3CiRcJqCS41AwgC5BBrzTUjzlRpuQL41DKtF8nFnPIC9lbZl8EjnpQMWC2uKvrC38HYxHveHvNmXFnihlpRk9+F1Nmn7HVnp93DQdlgnGtdppfH6e59dkxxnvZm/BQ5Tqoky9bFKzGb +n+RzlkNkmoDE5SxrES9DolFA0WCWVnmeHx6jLiA5ggA9kJJGfMnyugex5fGy5Q5M2Zxg4aKkO6k3ukasmbSa7hlU+KvikyFlvO4jeqvcGoSAgLEve79VybQ4pFkt+kv1lRywve7Remfw69EgI9kVNl465spJ3nwTmlJxnQ9FdA6fY6bR6MfqO9mttkUDGHQ71VnlNnHRkcaLNOnTtmd9knln7lnDgxuVnmYGYr5LKFESbCEHK0FRlEgOweVnE9l+ -YFczGOcmokx+wE7NndhJ2Q55/ba653zZzhJaiHysln66/Ml1imW9kwx4Jal2f4flq1ForybYhJAB7zFrKw78EEatbIOK3yGprF2VnV1lcakhiSghAHNl9oCKfZa4Cq9zvphq+B9zaV6CNsIYbAGumXOBXehSfG/cgiNrSGQHTCG7CX7oCJ66x7PLFvdkqJlozLFhAtMHevLz1lQCS2zb7oSpiAa9lrtla9kbtmOsTp5iRNGl6kbqn0H7jRbDFm25 +GnDeKWvy9kGlVZl252gb/w6hroAu5bpafqlDtqJllEhnHRlmqwdw569k0ia6A6dilpdEWSYi5k4U4Qu7pMw/w4NVku+4NQr/w6bOnIdnB7J0OSSUATRh9dzRIBo1CyUA5cAF/TosrkppVsCEdkNdl0iFySDYFBetnr1k7ikxBGdlGxiaJ9mNsnJ9lbwzZECdCw8mSkjQ9PrVSIFZjMgwQFnfJhvsFX1kFb5J2nV27Y7a2LF5elez771QhcTr9I6j -L5u5JMwI64xuLDNHiH6jskqdnL+n7VkRNluFl3JnkqmMxnr+m4hnLyY28nVTJUak2PaqtmC4Jl25NBlEBk8nwEBnsjRFVlAh7qtm4Z78H6xNldJpM1nRg40YEHNkc6yvayGw6Qkh4QB+KAJEArFwzs4KAjLPEi9oYmmYDnRgqNnoH6S/7CD1nT9kEDkyXj0yHn+R4VkNkmoDE5SxrES9DolFA0WDLVnmeHx6jLiA5gi79kPQmF9kJJGfMnyugex5 +h9ABXYDgmzDAw2wqpcATjH0gylWJh9nRgoR9kYDm9DBCtkTlm1CKT644q6JVl/2lhmk9dkhpl9dmncHisz+H5sXFPMmJM5yA40DkI5g8KmP7Fc5k1b77d5k2RhlxLcnQ0pc6m94iX65guk1NJs6lu9miZFphBl3x6QzhDgSoDEAYxAyAi49vb8xwBHzP2ljtH0aCbYixtiiDnv3EPABHBBYDkUdl9BhzSGnxli1nJVnBpkh1nXNnBxmXcyDHJhQC -fGy5Q5M2Zxg4aKkO6k3ukasmbSa7hlU+KvimuFlvO4jeqvcGoSAgLEve79VybQ4jFkt+lnUmPBaG1mOwDRemStm0IEn2kgUE5Px+ukD+6HBmafSGhlx0GbR6MfqaDnSamqDm7IFo1kuz6o64caLNOnRdllDlsVkuOl7VldlnO37xg5LKFESbCEHK0FRlEgOzHVnADl+GnDeKWvy9kGlVZl252gb/w6hroAu5bpafqlDtrbllEhnHRlmqwdw77Vk0 +sFlwkAAqyI+T5liS9nkJnvdRs+iKQiRZkfNlxumL+mG1m3BkWh5yBksm6lVnWQ4G2nNGHDOm1NrOlmvS5eBmT764hn6oZk0Gpi6ZFl1DkT9kezLlg63hzMclweaVDmHQZFVkUtKog5zTFwrwfA4xul0AyYxnvWlk1lQaSEQHidBnRnmzTbA6TALbA6nnxWBH565a9miOlC7HtyDie4vt4R7HYg7tDloszTqlmxmCckivZDjC1gDumDcBoEQABiDG -ia6A6dilpdEWSay5k4U4Qu7pMw/w5E1ku+4NQr/w6bOmbdnu1kXtmozwZFgHNl0OSSUATRh9dzRIBo1CyUA5cAF/TosrkppVsDXdnh9l0iFySDYFCcdlsNk7ikxBGdlGxiY+DmNsl+DlbwzZECdCw8mSkjQ9PrVSIFZjMgyRDnvdRs+jHn7ryq/VEpobA5o7plu1lILBerDbpCAkoHNn71QhcTr9I6jh9ABXYDgmzDAw2wqpcATjH0gylWKODlm7 +OynsBX3x5cCrZkbv5a5iwnBVwEHrCNdkH6TnYBBDlxVmrlZUdnASwXNkXZkRmmh1keakcw4xojGrBF9G2mR9QAENmwVkZDmmZIR0GmWHjuGG8Ev1FTCrxuk8B5u04s+6tCnvj50Bne9GVLHeNmdfxk7ZZCxtADclh4iyerTDACeZBe5YowiRPLH5BwpAdBQWG5pBRkdnkVnPDkNWZWumwcD+tk46kKDnPOlvdk7VmNalsthzWC6HCzViEHGG6BZW -7v3EPAD+Zq/tkYVm1CKT644q5Adl/2lhmk/6lgdnK1mncHisz+H5sXFPMmJM5yA64jltlnfJimgkb1nqVIFQ51+kDB5DfRLcnQ0pc6m94iX65guk1NJs6l6DlTQIe1mdhLwqn2zQHNll3x6QzhDgSoDEAYxAyAi49vb8xwBHzP2ljtH0aCbYixthODncjlnkAeUAlNlPdl9BhzSGnxmYJlJ9mK1kp9lXWzTYCGASDHJhQA6FlwkAAqyI+T5lh0Dn +wiYDaDn9dHQ94i5qcv4+nQjO4J0xgUFb+ymhmzFEug4mfR8BzMoy465+cnYj4/0q0qkB4ZSB54j5nBmmk4q5woVmsDkKRnQmxPjzCLgzMRysi3IyRqT3tz6VAp7xM9kQNm+Dlm77+DlnkByRKc9m92gYRQPWEINm4mQC14XFkI2kS1mpVlXWyrEr1QSDeD63G5Rm07DUbBqrDAjk+oCyBilRmobHK9mVz5zhJgcbiH4J2LIBEzmlBg4vjJDe5pWp -ywbrtmSNk/3GO4mRZlr/5wRnpDyjFm3BkWh5yBksm4sq5cckG2nNGHDOm1No9lmvS5eBmT77SDkLpHE/aven0vbJHruQ67qHlg63hzMclweYljmHQaWhkLm5KalzTFwrwfA4xul0AyYxnvWmhQ49NyEQHidBnRnmzTbA6TALbA6nnxWBH564CDmiOlC7HtyDie4vt4R7HYg5NjloszTqlmxm09m1mScFnqA5GDlCAL4WAV3ynsCQrq5aaTWx3whl +xjkyOkYZnaH5rRY3BJ/hT+YiaQpAxDm+TxtAiOCUAAY5lpOn1hAiDnmjlQDHbHBPDmI1lmBkBqkD15yDnp+kRDkujm9dnoNlqJkeKgsQb8eFL2l54jefD/k5n1lS9k/3HgDCouEhr65KH0ck6F5UIHU5FKekBcG3VnRe70H5torZu6pfKifDZcDCUx6JA3XC7qDTFgkyBVDAWzCVxl6aSO+A3Dlt0nEdnbG78kBjllFTSItnHxlBmkMbGhmno1mK -BBcUxYdiRPK/1lh9kHrAR9kH6TnYDQjmlNmrlYvdleZkQNkK5Ewpmvpk/Nkeakcw4xojGrBF9G2mR9QDtNkmVmdNm61k+oAMWTgeGqDabmmLCqZKR2TFxg5u04s+6tCnvj50Bne9GVLE4tn2+zBFkjrQHNlaiiQPKhIy4CykyBd1HDACeZBe5YowiRPLH5BwpAdBQWG5pBQPdn7ZkPjkNWaj1n0eEyOHy1lBjlijkhplZSRVACNalsthzWC6HCzV +DlRDlY1lhJnidgLWADXAhsaFtKe8zLHAqVTaDkEI6fFlVwBdbHb6lQpEwTEwZkmwGROnnlnB7KbPLXFIuNBiURyayhKBl0zt6oglBNThTVl8nFTOQs9l+DnFjmWFkItlXtlMR5qNkhmmotkvdnB1mvpk7VlZ6nhJlhPCFXBrlmKBAyJa0mBInKDmnNMmeqHiRCaP4TpnrNZnhHAlGxnDiH77CliEqPunR6HXN7ki76dmpanB7LdBwUgz5Ozm4DMN -iEHGG6BZWwiYAKjmeqGa0A8KmP7ECEFOvjhdEzHFuFkJ0z9NmS+KmhmzFEug4mfR8BzMoy465+cnYj4/0q0qkB4ZSB54j5nBmmk4q5y2Vl5emx1QzFndsBLWFxlkhvTQmxPjzCLgzMRysi3IyRqT3tz6VAp7yRPJxZAJnJYDnODmQjlyRJ4Dm92gYRQPWHlNm4mQC17ElkI2k1NnTtmhjl4JkzHQaV763G5Rm07DUbBqrCATkitnATmnAjjpl5Vk +EhshPGAXeLvbR0wyRPI2ITQTlFjmwRSKNnWjn8UiIdq/lkLtGB1kK5EwpnoTk6NnwpnKcwumYlE5EJlWjqV2DVAGPjkD5qlx5j9lKL7/758KmmcH16mV9l1Nn3SEph6EBkXVlXtGF9rm/JTcIdFbAtjOTaygAT1AhtIfwAyG5XDn9BhCTk0WAWjlty4D2C3dlc9m2jnZuBFMnb1kN1mz6lN1myplyLDEhS1NS3zF4zKRppSSDaDns1jxtlH+nXOa -LGofHY5NiJDlg5lzhJgcbiH4J2K4dnKqyiB4vjJDe5pWq5TkyOkYZm9ITG5nvDlPHQHNlrRY3BJ/hT+YiaQpAxDm+TxtAiOCUAD45lpOn1hCcjk0WCejlty5pQQ+jnx1lmBkBqkD17Cjnp+kgdnBpnQNlZtlqJkeKgsQb8eFL2l54jefD/k6rtkJjkMDlJjls+gQkCpjlXY6og46F5UIHU5FKekBcFm1nRe70H5torZu51tmENmWg64CAHNmifDZ +l6n3OaSzAqFk8ZpvjkpDr4hk+6l69mGpmTNmEhllNpqH5O9klVnw2HNiG85l9w66g4jxQ39n9A7sclpKJFBn5TmyFm3qnNWlFBmMxnr+nT0HTL4xjmGTnHRmnqk/w5bKn8B7Jtl1lk7hmCVlNiHlkxBllaXKJBmqDIjTk2Dm4lGMUIHzRyfgI1y8dxVEjjTAI6DJYRnELchlXDkp1IXdmoDJXdkBDm1lyXtkitnztFEyYulH11lKqlO5nU5msZCb -cDCUx6JA3XC7qDTFgkyBVDAWzCVxl6aSO+CwnBVwHXjkQjk8jm1lw1dnZFm5BQaVasel8dnLJnJ9mctksTlhJnidgLWADXAhsaFtKe8zLHAqVT8TnJjkEI7ltlVwBdbHb6lQpEwTEwZkmwGROmcVmvDlhfZm2A6KAHNmbPLXFIuNBiURyayhKBl0zt6oglBNTiC1l8nFTOSOTkejlQDGIphoVlFTQptlMR6Q/jz9lMiFA1nXFnijksTlZ6nhJlhP +mgXB7WVC6qD9elaaidMFxQjRTl4YLyn6WDFsBFPel/G6sxmGFJMDRoLyW4BLgD1HAIMDdBxvCj6oRVDyRPIa1JrTmkjmwRTVy7kdmUjmtqF5Qa3tnJNnQxnoNnWGmtTSDJS1w71lZLFD6TJ+jnhdls+iJLr6ml99lgWna64L27TgxpHp85oIwmhcIa0pUgDJ1CtABrljIIAcOQ7giONCNhlaGC5dDEjn2dnbZnLC7sQCljmivK2qG0llABlSplnj -CFXBkVmKBAyJa0mBInJ6qmJjkydnQzkbNr+lkmhKLmFUXQuWlOGHiH77CliEqPunR6HXN7ki7DbFV1kbcgI5l1Vn3cQHNndBwUgz5Ozm4DMNEhshPGAXeLvbR0wyRPI2ISUzlcjnUznZkBT9n4DkeTk4mmJ1lWrGsRFTRl/TnQxnHVhzgGkFYumYlE5EJlWjqV2DVAFQzls+gU1CC5lz4EmxlAaY11xBnZmh5pDnqtn3SEph6EBmVDmOIxBFkssk +l9dnvpmXTgbeS13jYUkXSLBM4L4B5Nn5+heeHTdnYzB8m6TjmikxTNn5ul1NkTRHkBGUD5GYFSW7Nsp/GJnRn1Clmh4+naPVkvJnYRlH8IMAR3WjPxA8dJ5JjOmBLgDxEBCpjhFBdulrZkJQSoDl3DnoDkBDmgzkUjlljm+YZtqH+TmHTn0KnO5mrEQPGl01wBgjZQgqTnVgARKSlGHRTkcnpX1nx8ENtksH44dEFtnGc5aSGjzHuDGRznVhE8ul -YzxYegHNnm/JTcIdFbAtjOTaygAT1AhtIfwAyG4bv4z6BujkZVjmzmwRRDVluTn8UiL9GsEmA1nTVkCdlklkwNmyplyLDEhS1NS3zF4zKRppSSC+zk+oDs1jydlH+nXOasDnwnGSzC+Fk8ZoIzkpDr4hk+6n7VmGplOtmEhllNpqH601kKtmN2LjiEPZK9w5DDlEBkjxSbDn9A7sclpKJFBlTzmRNkVXpFBmSDmBNl7pYA5ks+48BmQB7Lgxxdlf +xzlX+kajkuN67cjhlBFaw4AAWzCM1lxdA4WDgmJOmCbzI2uFAzkOdmr847AGwNngznEl7Ujm5bFVjnINk1jmoNkpNl9dn+Zkxjj6mTckAJDltGknEzQOA4ZQcdkEfCjNLBzn9NnfsHJsk7wmxMFkL5KR6NrJN5GFtmVKlNGH3E54Bmb5nW9nP9myFmWDk6pzTzl2hmLMmNBxRKCTTD5JGBipeZBmkzTtqQBCKeEiPFEVm3DkwCnbjmnORgzmOznb -hr8B7Kdkflk7hklVlNiHlkzTllaXKJBmqDL3zlGjneoJerAAVlzFnZRgHzRyfgI1y8dxVEjjTAI6DJYRnELchm5zkp1Kj9moDLj9mvTnO7DoVn0znztFEyYulHcNlKqlB5lM5msZCbmgXB7WVC6qD9elaaidMFxQitzk2QjsunVaKYPbABqoljvemFTk1VlbuEyuDHTlMDRoLyW4BLgD1HAIMDdBxvCj6oRVDyRPIa1IgLnkTlFznyFlUTm+jmtq +4zMbAuIl3tlqokmlnlAy8focng2MBxkCZ9m1B4BeQ3qig3g0DmwQR8FkdHE3V6pTlBbZb9mqSEsm71RlVG7/znOUEX/Ecyl5lG8Mr0crSnrAu4CzFlBleNnrcnz0pXgAw/A5tRFBLrCzrggD7zZ3Q94C78SdfEbjlEdn3DniDnP5mFmLiTnDylNFnZ2Z89n+2kV1Kb8Rt3I0AJ5TGgKnAqj6phR6ivzmd2pTu5TsmhFn0H5qlq467GTmzrFrCGga -F5QaKJlNdlqolVlnlAwXdnMKmDJS1w71lZLFD6TKRTma9lATkg9ltzlq7pDdlLg5gWna64L27TgxpHp85okdnBFkn+DfNwHNmhcIa0pUgDJ1CtABrljIIAcOQ7giONCNhlaGC5dCkTmC9nbZnLC7sQD3jmcLne7oLbbEDn+2kV1LcWwaLIyYi13jYUkXSLBM4L4D59mtlkCTnBQK+Nns7x7TmikzOtn5unqtkTRHkBGUD5GYFSW7Nsp/GJnRn1Cl +bnSnQz4Iwn+uCvOjvTTAay7ejfpixdBAZDOTYiAxFsmlgkk6IFzmMzmdCGBDklzknzkPpn5m4gJEBtnVzlBtm1znoNmdmnUCibGQnTDMdlMpxhfiZ/odzkEMzDHrizm3QHk34dNnHRnkxm9Om/LomD6+emJT4V2lBrGNRksom6DzGgBfgBeqgFBCOrCXyqlOzClybvR5zkRNl/ajCTlFzkXtnwTk7TmYN5VZlSTnszlotmRDlyTmduCZCw4doKgj -mh6FVkUDHrjlZqnf5lglmbA47jndKQMAR3WjPxA8dJ5JjOmBLgDxEBCpjhFBJFlALmBIBXjkwCnbG53jmdTkJC5FH42Nk8Nmz6nT1kPGl01wBgjZQieznVgARKSlGHYLnRlTmFkdHHKQZ21kFfp8e6AlmRamU/ZaSGjzHuDHGc6LqmkoaX+l5+FgDmqzlvDnEQBVJkqllOqi7cjhlBFaw4AAWzC8oC1vBGWTgmJOmCbzI2uEsLlC9mr847AHVLnt +oDi+zkDxDRy7Ktn+jkRdpf77kTnzULwg6ALGCGnZtlNTkFtkYr4quG85nAzYz9kQ8kUDG9VkC6mqEKx1JSnRfwrMSDUjChlBPGC1DS93Y35kIclrB6FjluTmwTmi5BiTn3dkMmbI1lnkDgxlddmqLmnjnRLkuZZd5lstgOqB2ljyAR+eRel5m+iRZCvznuyBZDlptx49mG9kWLl31mzdnV2k/ZmSK685mL2YGTk2kKSAZazlQZk8B7QunTqlJ56H -FG0Tls2oVznWBkzVn/Tkuzn+Zkxjj6mTckBRjltGknEzQOA4ZRA9lSLna9kEfCjNJDdk94bRunJsk7wmxMFkL5KR6NrJN5GGdmVKlNGH3E54BnPcE8B7helrjkHDluFn6jlxzlYNm5Dmk1n+sAHNnhDicKiuCmBipeZBmkzTtqQBCKeEiPFlLlPTkVLlFznhHgcLldTmYcEqMaOLl2ukHxK8focng2MBxkAhDm1B4BeQ3qig3jYLmwQQ9LkUan0x +qk1tniFnCnqn+lLhlmTnnRmUxl1ln19kiH5rTGr34+xHLclAfgSunNTnfrpsBnhjlBg7Takl662emitGtJllzqWBEu+6SemIlnjTkrGnlABItQ3twvbQsBJ4wjfNBnlQJFA9apbOqXDk3Kn01CuTls9lFznMjzbTk2FklaGnFmbZr/llB1myTnaNkxLn/5nFjEU1B/OTMdmLhFW0ZmAqZMZzLlfyCMLmOVmk/4Mam+aGhGm6jFDzmTHIpBnllkCa -m8GlFXoYdmqSEY1l4lpVG71Rl7+n0cp5lG8Mr0crSnrAu4CzFlBnYtnetkjEBiQCozxfqnpPQHNnN8Aw/A5tRFBLrCzrggD7zZ3Q94C78SdfGPTlt0m3dmVLl2WIlzkz9lJWm77GoF62llABlSplDTnK1nXZkUEyl+Atri/dmdrHxkhR6hsrmd2pTu5TsmtFn0H5qlq466RzmzrFrCGgabnSnQz5qLksskSKQs1nw3x4MBvOiq4LaFCqwgr96Y8K +kp8EIdk/o4daoUzlerQX3D/axwoDjIQeZBHXCriDsSGX9ripjWzkHzn/TRNpDR9neTk13SSTk2CwkLl2ukHxIo8LLPal1SBdmPPF+FatpgKybGylFRkkTmpxhGqnouHoOkILGphmUKEHVC8JgtVDUAxn66moyAf6Egr2rm4qGwLkKuppEAuNAvfi3xATTABQRSVbPaTX1jVDw7JzJZz1dk2zkkdkwQGCNbOdlD9rD2AeZlvR7rladdlihmaNmvdm -6Ij/gC/IoiPFolmbZmgLkUTmZhiPdnkrm/iqJTwgJEMTkDTn+TlszkuzmdmnUCibGQnTBOrl6HRbZyA2BurkAtlDdnCE6GtnHRnkxm9Om/LomD6+emJT4V2lBrGNRl+cL/lndsAqiQHNm6DzGgBfgBeqgFBCOrCXyqlOzClybvR7LnhpDujmFzlHLnVdmQLkjtkeZlvR4LtEvjl5Slvjly9mduCZCw4doKgjoDhtLkDxDRy7wdlRTkltn6fDTHZ1 +83EuZbvKFoYjHz7LhjMdlbLzlXBl3FAjloznSvBzq70DlZOraOKi+F9BohKrcW7cBFyDxXBktOYNJnyxZNJlTv5k9m8MaXaT6+RrQxcphDGyysgqGAoIB2tD3+wFalA4y1JHSLkbTkhrlTpjHzmPvIxaphDnHjnddkMjkJrknTlUWmhSCenDUWAPzlXcFOAk+uQ0DklFBQFmESnESLzmEfpbPH6uDRjr6Ksk5CnLf7FIlQ9Gd1LQjlu14sD6Z4qP -Fkn1nw1aCGnadlSDkGdkYr4quFi5nAzadDlOUFEBn01kC6k+tlglmozzhrkCZKx1JSnRfwrMSDUjChlBPGC1DS93YwFkIclrB4tTnYDlHLlxZAmrkeDn5n52zlnkDgxmJ9n5rlOzmrJlbBD9MabBx9kryAR+eRel5m+iRZBsrnuyBLTl38ZxumiZmKDmPrmVDkaXYutFi5mL2b16mwObvlkxzmee4u6kpTn5u5J56Hqn/FkZBkcaliDmUbn3Rnnz +9nEFEFkYzQrUxmdXxgrmKBnlAA5XJsvpg9xp2DELCo8JV9TnyAKeR6qD+rl1dn7zlbjk6xT9rkOzkL/wsfTVGkjrmDLljrkqqknTkgVldO67+g/wnRAl+LhoFQy16Lrkxmh6DGvVkk0HenYiFkUE6W366LH45GpUrLpkouneA4NDCumDN6iL6QiAx2YJC6kCGKygCndleCjxuA+Dl7JSj3EImSCIJYrm+1lqNw+7rSTl5SmErk+dk6NmMVmX8Bi3 -kxzm7Tkask/DbJZko9kKtmJNl2boO8A+rlBg5pTlibkIumhNm7RmsVF6SH7d5jjmSekyllPznaWI/5m/TwSVEWiAHNlItQ3twvbQsBJ4wjfNBnlQJFA9apbOqrZlP3ES+xgbnOTk8jnMjzvTkgNnMbIqVnrlZqVmQNlrrnpRk/Nn4FnFjH+zmdcC/dmLhFW0ZmAqZMa4blfyAerkKtmk/69Dm/cEsm7v1aRqFhmwyH7HzkCakp8Frdk/o6IrlmiG +BiBhrPbX5iqtipDk4+nmgkkTn2lRRdmTclZhFwcaqfKg+pZ5GyS4/1kohwogCXlk7YLSADm4BrLR1vCz6LOxluWhU7AntkkjmFzk7ZkxNBdLmx9m+TkwNHHVGBJkErmcznDLknTmmVk9mDWsSTLnMzp46yafwmwiLrkTThXZEVWmJ7F6JEUBEbdn465cUG6PKejqjg6iVksTkk3L0IBVABz4beXxIOy7fTOkA3Mj3xBUrxsRA7Jw25TSrnfrme1n -s6rGDmGLlerQX3D/axwoDjIQeZBHXCriDsSGX9riphgjnPTl3dlt8BNpBuDnWzk13S2bk2CxUrmp1k+2Io8LLPal1TK9mPPF+FatpgKyYoIlCzn9dk/3GpxhGqnouHoOkILGphmUKEHVC8JgtVDUAxn66moyAf6EgojbletmzLlbdl7pb3zBBjZM9mDGJpEAuNAvfi3xATTABQRSVbPaTX1jVDw7JzJZzlLmGrlYll89Ci9lD9rD2CLrmY6lRCgJ +01B6bk+TlUBDZtGRkEVumsRFTRk1zkwzkhtnpVmyBK13BqUSk6kjMh/hh8OjCzmpLlvkB9rHQFknWmfilmhK4gZcC6iyHiO4UhmXlAX1HEGqFsCCC5+Ma8FYtbnCC41eFmtnu9nLOCqGC6opjYC0gDRACiYxfADclh+mBIt6ksEwNmBrkyrkKNnscR/rkb1ktuEuznCkmN1nuzmiTyWyzKQmKtwbBnN3r7QyJAkObmXn7UcHGJk9tnXzYwqElrJd -9lihmfNlL9m83EuZbvKFoYjHz7Lhi/dlbLzlXBl3EATmSLnRTnSLleaguObxTkebb7UHaOKi+F9BohKrcW7cBFyDxXBktOYNJnyxZNJlTv4TbnozkVjktMCzlni+AHNmXaT6+RrQxcphDGyysgqGAoIB2tD3+wFalA4y1JEHLlWLkoVn88AnLmveFnFk5Sp1LnwLn0Kl8Nk3sBhmgDDDUWCMrlXcFOAk+uTYLklFA0FmESnESLzmEfpbPH6uDRjr +0487H1THYCG/2H6tmX+myHZkKHfjmkuG8Ma1jR7KKBSyygCNmQr94IDKCVTQBDy4wTJlYY4wtA9rk6eTMNC7jknNkITmacn2L5LOkM6AEDk3slXNlfMQIpyqXzu7Cm9S3TjODr7IDJrwdjlpDmf2ZgBLcKBA9lOvaM+4pT5sm5rZ6GwGHBH47nIbmzNlS5ZIqFDz7ZeYvulVgog9G/O5dIJDK68gE7yk87GfiG/MFUTnjaZyL5XMo5xmpF4Gk4gm -6Ksk5CnLf7FIlQ9Gd1JTCrBxFxpaZ4p7DnEFEFkYzQrUxmdXxKblGYL1tmljDGemork3Cg5XJsvpg9xp2DELCo8JV9TnyAKeR6qCbbmr4Dbbk3jlySBsdC2LlZrl0iz09HfTlBAm/TnBjnXLkztnaVldO67+g/wlZ9k9RJoFQy16M7kxmh6DEPSmGibena2FkUE6W366LH45GpUrLpkoumbjm31nEQD4tmJXQJ8DspjpEDxZjT6T/4yemACGKygB +ns7netreErnrmZMwyeysBHUvrGV6U7kvbFy7EhqEWJGBDF3bkYtHB7L9/yrYDARTUyRLkwQBDw1wYbTq4gOOrNLlA4woDlTblxbk6bmzbnW5mlzn1OHXTZJNm2ukLlmSBJ5gAv8oPxoWVBA6YLtQtFj3NlETnVSlCbnygjuuz55F7TTIRme6DEi7JyRoqEAeDVVmbIy72nElbh2HIcogN7hzk4FGLKH7rkbmnpqFhsHkZxxMGmhEa17DsrRKJzW7 -D9leCjxuBujl7JSj3EImSCIJWbmmS5vhIrrlMRkaVmFrkztlJVmX8Bi3BiBhrPbX5iqtjxjnR/Ytbl79k/3H2lRI1nwkLbBE8rEgkYh0Kg+pZ5GyS5gc7nVnEQAazk3CjdPR7cjhFBurQ7YLSADm4BrLR1vCz6LOxluWhU7DldlkTmHLk7ZkxNBQbk2znGUowNHHVGBJkObnWrnvjny9nzVk9mDWsQYbnMzp46yafwmwiM7kTThXZEVWmJ7F6JEU +oBkSVHG/ZKs6Lzkd8mkjwPwAX1hgcH3yCxbG2Wh5CA6+Qp1Rs4Hqbl7Xh/bnQNk/sBhrmj5jyrDVYSqbo5Smt5ledl0VkrblAxL9EL2Vy8HTV6YT4pt7FEdTPxmsZgO7maQApmk/AF9v7gTFecGG1Eh+Gl5B9qLpFKJNFoOoh+F98YTuIwA46XbbpkTMnj7lllmTkr8XAL7nbL4gMYh+HD2HdCkKW5K5nVgprIwKbxoez/wZr7lGPbL7nhArtSos -BGN9n465cUG6PKejqjg5VVmpalQ7k7OJglmNtl59Qn+Jz4beXxIOy7fTOkA3Mj3xBUrxsRA7Jw25R5bnErmDtn01Cz7mxczZtGRkEVukOzmdplIbndpny9lg1myBK13BqUSk6kjMh/hh8OjeLmHrmIdnCvLtogAulfbnza6TKYgDmMrYJi7m8T87mXlAX1HEGqFsCCC5+Ma8FZkHnCC41eE9JkcFkXtn4sB9NjUjmqGC6opjYC0gDRACiYxfADcl +ZZjHGEE5MyzcW7P6bcW7uMzX7mMMJ9ewXtYHZIDHEbDzHtGR1iv36g8YLNk8clE4HXA6eSKJuEtJmaNFXrkp+HnhGdn4aCKe37DU6gHkYFIp+ErHGcf4LQrU1l+bkwV69vxoUBxnZdNJi/ymWTeHwaADPsBVekUbmxuBa7k4LnvnAVFmJbkSF4oX4qrkm7k+2J9oAaLIPAi//E1FbRoSIGqGJSLrk9fE8Zlm8lq2nxP44bmDC4FhBJMpt7TmBJvi -h+mBIt6ksHFNl67kvTkwQGUS6Zrl/VnPa6k7mT1kNLl8NmiTyWyzKQmKtwbBnN3r7QyJAn77mXn7UcHGJk+dnXzbYdk0qnBZJo8ly+lTrENyHtgH4xmFhGozmkuFzLkg5mLLnGTlOqi1jR7KKBSyygCNmQr94IDKCVTQBDy4wTJlYY4wtC47lgLkwQEebwZ7mCLH6tFLOkM6CIjk3smZtlfMQIpyqXzu7Cm9S3TjODr7IDJrwzTkV7lzTnCznCvI +IjFgxAz4whVQDnLi70Gorl+bISyDwHHvnAxbkDrmKGJFnr2dGKqlLbmBTkrbl0zE3mK/6ArKi4TmbX5RtnKP5v+h0HlykoWNnG9LG9I/UYCjlapnYlwkDEIwlpkRemLrUAl4DhdAV3wY3yq4gJZifJA0zk6sEHTCf3wUjQiHkwQG1OBeTk2jmxcyqmK0jltenAblaNlsbmduAg9zMDpq2j6SIMf6tdqmjAALiozmdjnCvKjxC71Fvr7GBZPJnGHw -3kGH9lOvaM+4pT5sm5rZ6GwGHBHpHkk0HOWn41kgxq2nFehLaTmejHjLog9G/O5dIJDK68gE7yk87GfiG/MHAlHGvT67JZxnSelTGl86GXrr+inmcxn2lDRGW5GsBHUvrGV5VgpfsFCjpKZkWJGBDFGHkYtF37knRnyCBNiQHNn9/yrYDARTUyRLkwQBDw1wYbTq4gOOrAblA4ygjn8HkFbmwBgx1lkrm+vIbZGwBgVblNsmKEh5gAv8oPxoWVBA +Rr7+zqFplJjncy7rggd7xIgAWADRKBEfbu5E3GBcTIQTleCiNugbjkANT3OT/blwTl7jnA7mIYFSfqzNLitm/hk+ZnBtlXWyAkBA3ICRDftwnhp4zKsFQlbnZrnr3gWGLqpmZGqTp6Fb7D0KDrFBVEmfLHSlZfpZ8FyBl+/wdG65Kns7E39EB6JFYLyZYpwxN6lwHl+GIyXS/tL0jDHchInZx1AfJBwgDSgC09CeDkrcGADDoGpFHn2xFwtnyrlu -6YLtQtFh5tmCzmxHmtbnCvLygjuuz55F7TTIRme6DEi7JyRoqEAeC41mbIy72nElbh2HIcogN7glk4FGLKFEHnRKJU/5xMGf2FbCFbGYa17DspAnlBRLoBlqbnT+BKs52hlo2FqznEQCwnnXtmiAoPwAX1hgcH3yCxbG2Wh5CA6+Qp1Rs4Fj7l7XhuHk6eRxE6q3Fi9mHblRiGqbo5Skz5nPpnT2lObmbhAlIAIoyJpSyWq9mkT4pt7FEdSQoGV7 +Hl6lkjgDDrkoTlxrloTlErltxAlQktJzWoCJqKZ9nfcnLRlcfid2CLrklC5BRZZ+YFf5EXxWKlx+J+jbP6LAdmR5bxQCrO7EqKN067sJgcZkqRw84ZsG26l/HmSeEQ8wzR6W154vZ7W7YMHjMn8+n8cmwGkQHRFbBdrSwunfGxYnlvE7Zlq/0zZCD7OChdA8KjZvgGMRTXjlRph1kHgjPYCFHnAhhHHk7Zn2zl67kKLmfODX541ZmBpkQhm1jlKD -lRDk3HmaQApmk/AF9v7gTFecGG1Eh+Gl5B9qLpFKJNFoOoh+F98YTuIwA46XbbpkTMmSnkPlnQMH8XBKnmXSlz54h+HD2HdCkKW7a5nVgprIwKbxoez/wYanlGPaqnnwrG92FfrxfMljdHFFpclmQZzcW7uMy2nmMMJ9ewXtYHZIDHEbDzHtGR1iv36g8Y51YWXwmqJzlmtv6bPxTuFyEKNYyDllnvbyEKhxwaCKe37DU4RnkYFIp+ErHGcf4LQq +nHVhxdBWRn47Ei9k6FrVm7dOTFnDvHnKlj0mlpXoT46Mmm7RnVirSnkp7n+6njXyPPAUqHDPQoMhZEDj+hVcTJ8CsXi70EPYAOHnCHlzjEA7muHkELlYIRzSFG7l0Zn0Fk/PKrOD0YS2yiMwg4NkpNbJsSt3jhHmo7lCbl45j42kk2m0HEFLBxamgpZzrHuz4GKlG2paJHy7FWiH806KqHNjGzjZyexAnYHp6SKwL+wjRbWzQ+0zNiiFRyDQ58LY -V1m37nkjnBFmTVDTsm0+AHNm6jhKxQe4B3hh83Ri/ymWTeHwaADPsBVemJ7mxuBrHnbG6HhDFbnuTkSF4oX57HnIjl24x9oAaLIPAi//E1FbRoSIGqGJSM7k9fE8Zlm8lq2nxP6B7mpLmTFl2zLENmjXgFhBJMpt7TmBJviIjFgxAz4whVQDnLi70E91l+bISyDwHHvnB/7nCHmKGJFnr2dET1lBUm8NmILk1ND1DD0YQhFT7sxOY5INnKP5v+jt +IwmHIjnAD4WD0qSwDIIWDSgCwDLUVLzYChVkADCLmTF7kKNl4Lkx9lJbkOUCZUY4mzrVk17m0VnjBHxZZVEiSNEv6BH3juxoUKIGIGftmGLkORgjFnhMHjDlRo6LnyxaGA0YXFZhOl336+YqrQYugH+2aMKYH5mcmneA4RaIGNJ4MDaKSspmJ8CZhBW4DfTIX1hF1k46AfbBUbkAig0omw1mZhjiHmyTJnUa4mRHjmXHn0jk+HmMjmbhAJQGriog -nlykoqjnG9LG9I/Uacv6plHJrHOdk09kpLnntk4UxvrlNsAHNlpkRemLrUAl4DhdAV3wY3yq4gJZifJCmLk6sEHTCf3wUjSLnkwQG1OBWzmVnnE0bSDECYn0Tk46mijnPOnL9mNeAg9zMDpq2j6SIMf6tdqmjAALgSLn0DnvLmMDnxlCjxC71Fvr7GBZPJnGHwRr7+zqFpnELngDlhr7SzAYHQHNm6opnhL4IB/ghPNCpEAGi7XGAM5AY8y70GEr +dSzYQ5zCtMKkhT4BCLrl027giFIbmX6Est5go4B95GlLAZGxYoUXwwjnh0wsGE3qIeym4LQvXouJbiiHet7/nl4Wzqjl5xlEJ5eaC3ir+cTRn5L2w98xYCyWYxQxCnPDaRkpZjLnn0zmXdklHm67nflmQfxV+LVHnWBm1HnqLlCdjs67cOJ5+hcNTqSJT+aqNg36TNnlo9C8lksUbbaZ3b4tinUQFs5HG36dKm02nOKzXCkFBlqa4EaInqmyWg67 -lcn6RSAwkID5kZFnzrm1dmIYFSfqzNIXLn8dkXZmCdlABiAkBA3ICRDftwnhp4zKsFSoHkvblHrn4XmNuhk3oSS6Tp6Fb7D0KDrFBVEmfLHSlZfpZ8FyBl+/wdG65Kns7E39EB6JFYLyZYpwxN6mJnkqJBiQA96JtMAHNkyXS/tL0jDHchInZx1AfJBwgDSgC09DOjkrcGADDoGoANT3OQknkIVnAHkllkjgABjmhmkK1lMTk2rlZSQlQktJzWoC +YjMnx0GNbAyeED2FQ0ooS5yjQQS5ennyemKYaiXkUSQj2G1rnkkrtmSGnoSVzPf48dI1EiGWSNvAANAnOAElmIXnhVmaQB0nkwkKV5lXZQEHl+a6VHmPdkBplWBlyxmXNmfDlABjlUAZTLUyJ1nmuJzgLQpShNQnXnkJ/BsMrl8aCY6yw6QjKf3rfr5LtYkfwjal7+YpDrdoKJjmmZlalHcphPCg0UgpMlSmgVDAfwCQ6CwcnvySCHnUblrnk7Zl -JqIhDnfcnLRlcfid2CM7klC5BRZZ+YFf5EXxWKlx+J+jbP6KTdmR5bxQCrO7EqKN067sJgcZkqRw84ZsG26m5XmSeEQ8wzR6W154vZ7W7YMHjMn8+n8cmwGkQHRFbBdrSwunfGydXlvE77TkheEhLAfwQHNnksyobDRFAsnHemBNTizahekC8UzTFh2Dn7mjPYD6rkBXn2xHyVnVy4rnklEGBqk1ZmBpkQhkFrnMTnHVhxdBWRn47GUDk6FrVm7d +YxDyLm+vLm9ZYZD6VlY/FBUnLbnHTk1NDzdSmx5c0gEwT1HHLRwjfgP2Ao7kCblUolCbkqWQoWGPZb4Z6vSkS7nZBYHxzwE6uclyU5oLEpNp1XmC+FQLFFTEPt5r34X37MbazdZ6tmXyE7HYDNluHG4xndXkM7necEHVpR85lRkinaxELjOLC+H9n5SbmPBEmxnp5m1DnyGkvTmBBRRiDHHDSVlygFwpxYWLo8TH9qNbqdrn5HmosDIXnrTn/bm6 -OTFnBpXnKlj0mlpXoT46Mmm7RnVip3XkInmjaGcFnInkvnkP1mPPAUqHDPQoMhZEDj+hVcTJ8CsXi70FGNnznmp7lIFkVnmlzmduyqbrstkp1n7HnbEirOD0YS2yiMwjNNkpNbJsSt3jYXmzTm4XnzTkFPgMoIyNmvv6SCF7d6edmX6G6dYws7dAFsJnqa4v1H5hFWiH806KqHNjGzjZyexAnYHp6SKwL+wjRbWzQ+0zNiiFRyDQ58LYhrmguQTq +bkByCnHnGbG1P7JYgMRnlnk71kVHFI+mYChqWEGUxPQJWhSPFnsaC7tICqGLrmCxg97lSYLtgHiY6APpsJlUy6v86OgrfxltaIJHkLU4DR7h0xFDYmLSiQETJYM1FSXnB7KXsDg9yimI+yaxEDuTrMSAsIKluxcrJOTk4f4JQpHXnAzmr87Xl6JXlE5xzSFQznG7lNsmKEgwpIDk52RAn7oPzlzFI8kZSHDtHkRHmipSUdiWMZTFl+MpOWkI+F1C -DI5khIy5ni6jgoELBaCMAAvaSiyKrAQioJt8zzSSLmTEnmhVnIFmFmKg3l7spnUZJ1ly1lwXmRXkIXmXbmsZBVEiSNEv6BH3juxoUKIGIG9dlvLmvbkfLk7RhZbqfbm6vImq78mxalasV4XFZhOl336+YqrQYugH+2aMKaf5mcmlB7nKL48LR11lLLlq6gRaIGNJ4MDaKSspmJ8CZhBW4DfTIX1jUtm5JymzmA3k0onR1kZrlbHm+5nZS4MbERXm +7DCmSK5rf4J7Gd6zsakcBkjt6amGn7nJZmelkSeGFDLZV6V+qDz7+9TPhr9ErIj7W8ASakTVBH6bdbm2DmPKpE0Th6KPyDbUCA6rku7cfDevyNbqHtnnTpc1lCHk0bnSGTH5Cq3EudkRrmNFm77HlMjnznQzmrJlbBCnIhvdQAKD3JgKtnlSLxLl3Zkizl146UXlPcJ3Wkqula1lo66xNGMWHu9HAex2/4R8oGCEqFYitHonmq8aK3kx0FvaG+jK -MTkq3kqqlq3nCdnh2oGIaLTkeLmkhT4BCM7l027giHu7mwU4KmBAEYB95GlLAZGxYoUXzxukniK6iHuPYeym4LQvXouJbiiHet713l4Wy6Tl5xmPnm1xEw7m9rmapKmtCowgmhwm4jd8w9baWYxQxCnPDRtleCgfbAT7mWLnuHmwBhCHnR3ltlzZ4ZiHmbnkSHnbnmYChBmHisz3G5Xm7nbEQjoGD7z5HZ3lk1EqHmnHb6zGTrFLjZhHoNjGXiaV +SNwmjq5cDcGRv6p+mo2CgfJBAMLPOjTnqfrmbjm4HmO+RKLibnky5HGhqLbnpXmyHmZXmYCjaylirDxuCnETz/529Ex64/ToPFmGLmDpa9ZlzYGlVYo4ZrnzKFF564lNmoQrt5KynkgJlb9Zx1JlCD8xxD7wl0jZkQ05ByIAInbq7kUbl2WLankm3kflldBFl7ltdmaZEUrHEHnk3nbEgDFgUiRxogV7l/a6GRJ9CCAD40Dlt8jhKlaHkQ24Ix4h -3lHhGGzFP2JIwr2UaJak67YjMnx0GNbAyeED2FQ0ooS5yjQQS7uz6iQFahbyemKYYPXkOM5iQBqeBEaQHNntmSGnoSVzPf48dI1EiGWSNvAANAnOAGlkpZjsqr+XnAhjLXk7ZlXZQhXnHxnCXlz9kBpk/TlBpk7XnRXl7Xko+nZmpy+T/Ji5RkpShNQnZ3kJ/BsMrl8aCY6yw6QjKf3rfr5LtYkfwjal7+YpDrdoIFTmmZlFTngQA7jy0Xk3Chsg +FH7FI6T7q8nI2GNwB+0Ivfbb/7zOEonGZUw9Xy5hk6gaO8nsKL3TIgvGHSld44DJbOSLTcn5ZZKebgA5sNTSeZDnlttFfikrXm+xChqRQ6ArD4XDpze5bUr5NSLYCT4Qj8mmCRpQSxbm53mHXw2jwL3mudk77Fd/YRu7k5nSHkl3lHTli8lZXnHbHv/aInDQJRprmd+JiOTuyD73nPxjvzkUakVBZW8k61ma1nTFlMalTmna1l3UGiskmgqonEAy -DL2w0UgpMlSmgVDAfwCQ6CwcnvyRznkp7kR3mIPlTphrXmOFGoPm+JDjhFL7mvjkr7nrrltxDzdSmx5c0gEwT1HHLRwjfgP2DRHnbJ5cnl4jlhNDB8J4KGGubaTmjP5QLGvSkDHkLYGbd5ifYnmFQhZy7HudzmPm7BGV5lMakX37MbazdaTHo8+JXq6mLHN1EOLxQBGK+GjMH9VGk2k/zEsH5rf7GhnKu5UNGk0GyDltyGHBlxbkhm5QDk3CiiML +mcPlM34KGmDjARLSowh+QLz0SdwxxtBHwAoMCrZyaOlA4xIPk4Hm2zl53kfei/sDhrlb3kXRF9jQr3lEDl24wgZDlVytCDAFk434hPzV0ayBD8bnUmmlXk/3EGHgc5lz4Ev7k6TmcH7IoHtOkWJZzREKFEdgG7/4wEH6eI6iKrkHOrnc3TlnjbeymIiNsLXXC00RWljAZjyxSG+B8pmmCTFrDIPkyPmoPkbnlzbkgG43tl+2AqPnNzHBmiRVznAx -UgDFYZygFwpxYWLo8TH9qNbpY7kj3mosAWLlj9kknkz7kByCQXnGbG1P7JYgMRk0nlxVnjBHxZYOdbbRit+J7QmPLnOHK7tICqGM7mCxh8nlSYLtgHiY6APrE3kw9av86OgrfxltaJkXkLU4DR7h0xFDYmLTv3kcnwM1GQ7lJnmJTktMAonn11mjXiXsDg9yimI+yaxEDuTrMSAsIKluxcrI5zk4f4JQrZPlprk4DlR3ne5l2LmuszwDE1nnNzHB +b+h6rlM0xbLww6ScFn73keHjQKk2cHECQDQaERKH1y+lL1ZY3cZbmqVJnOiZ3NZUIFppnCkZjKm/hwHln5YBa0w2JLL9k9+ySQw9+wzKmxDxDkFySn+ratSl5SZQf5s7Fg8lk+kwgHcrYxNGS9Ebrl1Pa8dkOQ4/LZwZFa0FdgSBR5aHzZg6U1Es7F/cR4BYSxhBS4WJbQqHeHEAJmBgELL6bQYmqLyJKWlrNgZggE4Pb0qmopGjKmKM4DimkBIi -mgwpIDk52RAn7qMrlzFI8kZSHCKXk4XkG3l4XnlsQuzol9nViyInHxuJOWkI+F1C7DCmSK7BPlnvGVVkoaoYpG87lM/xbVY5FJg5KbxbZV6V+qDz7+9TPhr9ErIj7W8ASakTVBH6a0HlxNkXtnvIAfDk3Ciz0RqYp0jCURZ8SAS4yNbqsIIiAyNboldnnTqJGLAXkLnlzjHYEDR9nknnyrA77Fd/Z8g7ptniXnVzmSXn2Bm7CbEMT3JgwdnlSLbr +BmkZ7Z5ZhAKBuy68FdbktrKFiQoBJxbRkVzfs4MVo+3ZS7m7pkk3KzYDiv6kjCRQSYiwWFKqAg0jD8ZSnIgbelLnnEFnG3lxXnLC6qOAtdkW3mKPmZjHbnns97ITmABmRLmcnlczncnlsRlV75lKg3uj6ym6dI96Cr1T6PlxpnWckkTnyI7sunVaLMpIPZbMKZm2kpqku6alCGT5nMqkGDm9ObhRKZc5HiZ7BKzi62lIP2EttmrtntZbG3rKVA0r -l3Zk+Lk0VkCTl144sWmV9HzR4nqmwqbBdn1JLAex2/4R8oGCEqFYitFtXmq8YIvkx0FvaHRPnu+zovmjXg2Cj2WjAxAa0qam4J8T7/YfJBAMLPOjTnq67lErk7bmr85D4BG7l/VkcNnjtmABmTtmDTmr7mduC3txt3KwJgNxmLtkx64/TrUln63nKXnphJK8km3lWQmOZH6oadMlrnzKFF567ujqWPLWWmntmUXkmHl9SofcRStltjBMli0PRjcz +Sdwyy4zCgBqYrCOCthHzSTH5DUyirnlOHmHXxZEl6XmOFEGXkEPLF3nqylU5kEPmYCgfdmw7q2RDpaDwG7Vm7qEQbblXnH4vljEJA2GvzFOz6tXmgyls+6a6ZQ8bm1E3Jksvkj0Ewf73VB/ak7+bDHG0vow5YNbnuLzBRGi3lIDYGzEoFKwelzja4BmD4aI9H5V5K9m9EEYQbOcEaSnJHl5UayqAs1Fj4QegzOkC9xH8OD5tS0cz8SjzSRqlmPaZ -8xxD7wl0jZkQ05ByIAInbLHmJ7l2WJkvlA3nyVldBH7bmj5g0vmaclCLE8LkctnOzlCdgDFgUiRxogFvl34aJSbYrDyAQ8vlZVkCTlt8gNdlizkQ24Ix4hFH7FI6T7q8nI2GNwB+0Ivfbb/7zOEonGZUw9Xy5hk6gaO8nsKL3TIgvGHSld44DJbOSLTcn5ZZKebgA5sNTSeYO3lttFfikFD5erA6DC8VkT4bHOCEDxXbSRiAd8xbUr5NSLYCT4Qj +aXmBKjnpRKVzoPmW3lbbHBnIqlzRPkuSnWSgblhKNatEA/2TYUlcMTNEAPAQizma3CtnmXjE6lJ0vmz+GhKLujE92EMC7ktlx+KbClZnyJunFHEUvmsZ73S4nOyOcLqTbf4ZdvnOPnw3kk3II1wbLSzai/NBWCJEir+ibv6rlRo5GHUnl6sjCvmOHlzjGnfJE3lqHHE06kxbvDlGVm4Xn1HlzRlCuEJ64Nxl+eTOHK65InET73mQ/F91n+Y5ZxL6 -8mmCQdTmlnnSGQ2jx5vmx9l+FxUDqnbkfNnwXlfNn0nl2vnHbHv/aInDQJT3bmd+JiOTuyDYLm7xixDk2372UY4BaSK4DcFZxKWyku6Zt4bo64Gk5Lskbjl9nnQ7ncwCnLB0XnDGKlEhbZSApCIWA0wAVvCYbBh1AiUyksHnvlGvn67kLoBXvm/sAHblVvmMsFT6mNdklvnIblkuAgZDlVytCDEFk434hPzV0ayBDl7k6PlXHlV7nGb4CJilRmgf +DEts7hl4AkorYrt6JFBZy8K4755Z7zN6HBJ9MGcEFQha5LEn5ExHmGuZu8m1Xknvnrzgo5ZMXmFZY/z41JZKpGOPnf3npIHA8knySF9oSUT33BX3yCxKIOxrnAPGBS4wXaSv5K7MnzZr0o4zvk6nknsQq4AszlbNyty5fqlGblOjlm+mZbn23lkuC8342ZQsIBcMTMdkdRF9UkthgfXmN3nyZRcYKINJncZJ/YWOIG+ajJFBny87nYJY6pauUF2S -lixZSSntOkWJZzREKFEdgG7/4wEH6eI6iKrkGyrkQCDvIBwUwHNnlnjbeymIiNsLXXC00RWljAZjyxSG+B8pmmCTFrD/7nGvkA7SmvmE7mQPC/3zQw4MvnA1lW7lXWyRVznAxb+hNblM0xbLww6QGFm/vkeHjQKk2cHECQDQaERKH1y+lL1ZY3cZbmqVJnOiZ3NZUIHRvlqw7n66UYFuqSnp6zTxa0w2JIDDk9+ySQw9+wzKmxDxDkFySn+ratSl +oL/ZomYu1Bxo49SSN2LdozhbRMTgRl5lYBXOGrQ7P6HPeCh8mOwBzsm1yiXrnjbzcB5GmnfHntXlZBYk5Fi+EhHoqJYOLwgBGIZmYpFdfonmGvv5ZGYcrZBEF646Dw5V/4O4b6Hm9C6GibBm7AqGD5KFeaglGb455OrIu6xFm1iQ4p5bRB9zlsvn/0KrrTMDS4abERzTIC7I45oHYbA33BmKSl5mxXmivl/tAQvkKPkVZlSIK0ZmO5luzll3k8gA -5SZQf5s7Fg8lk+kwgHcrYxNGS9Ec7l1PaQ9kOQ4/LZwZFa0FdgSBR5aHzZg6U1Es7F/cR4BYSxhBS4WJbQqHeHEAJmBgELL6bQY+nkWJaWlrNgZggE4Pb0qmopGjKmKM4DimkBIiBmkZ7Z5ZhAKBuy68E0HktrKFiQoBJxbRkVzfs4MVo+3ZDHm7pkTPmoSBovmd7lakwF/KZgK3OJ/eb/t6qAg0jD8ZSnIgbek46DdeHUygAihiPnLC6qOBUvnE +qDnAYZ98IvcDqDFZaoRrgAVGN3nqfpEL7wsQ1Cb+MbrIE3Pmm2kD7mokK0BYUSQJKIXOEmGGsNh2PlfQ4wSBMIHCfkuE5+0IO0AO5i1fnx2kEqZ8H65Bw5PziB6yqFi9HznyCxHh6HE0HbMyj75o5ZaHzYjwBY4BXnnHGVDzs5DZ4C8frPCj3GCsSz7Ho0AQBPmsMGeTkz3mgvkjln6AgF3m7H5G9GZvmXxnZvkxDnJ1zuBgrJhPMl/wiDhxZrlM -fnAiksQoyhIhmkTtmL9lQNm2vlKPlp9mXKSxRh2vA0lmp5Q96Cr1TMfm+s66PmKjnyI64LlC5nIBbznwI25fNqR+EjkHW8nsamTmrdObhkFzjaDKbxYwa5mIs5M+kgtr9XnfT4fGzePgHNlqCa6oDKVA0rSdwyy4zCgBqYrCOCthHzSTH5D7fkgXkUvlZEnIPnf5HSPmk0lz3nqymM5li8k7nmr9mw7q2RDpaDwG7Vm7qESyHmTTqffmNvljEJA2 +3mAmDa1FlE6MDH0fmhpErKqdcHQs5/krGF4IwnDSkPXCrARF2CPMgjahc8TaOwNIHIrmsMHQtkgvmhfmatGSDn7jknoEvl4rvmStlcnl4XnfDlvHCLVnpKBarnwXoyJYhYIriAQFmxtgdkEVbmy2JqM65uZpF7E5EQkbufl39DukCO4AQxB/yIsvj3yT3ixWtCueBdhzHcmhipPRKofmz3nxXm/rlMnkL/z3KGAbl7nknjkgbkMlk8gDMjm8CzMs -GvzFOz6C+Hg8LV9Ga6ZQ8bm1E3JkP2Gy7FYzzc051BaDYK0vow5YUhm08HedmNj5475Lc5GSFFf6wemQ/lYqmitFD2HtjELOH9z7cpIP3k+ylntn6Tm1Vlc3lQLDDXm6oqvABj4QegzOkC9xH8OD5tS0cz8Sji3mGvncXmBXnSGRKVzXvni9myTLy3kVKDHPkuSnWSgblhKNatEA/2TYUlcMTNEAPAT1vlUFnZwCvG4vPldzBGXlx2JHE6CYLujE +TKFgcjmayhgVJWQxI/m22je3k/XzsZraNFPNrrLFLQYSZZJFmg2ELc7hRGiZnws5gZE6dlNXYOXb08FZ/bjAEofY4xo5frjsa6dY4/lOqgL0RSeQrgLFvi7I6a+lcpj+KAueCMADRWkpZjItgHHkJvn/bmhrnyPnl7nAikNhYcck4hnpbmdpkEfndplHnl4Jn1LRWeTTgaJLkCZDPfANxl5Nk7rgTdYrrnRdlJ4GNY6pebPsxLEIFllrHKorzW5x -92EMC67tlx+KbClZnyJunFHHgfmsZ73S4nOyOcLqTbf4a5/lifnjPm2XngQAx0D/5lw7k3CgI1wbLSzai/NBWCJEir+ibv6rlRo5GEHgi+GqE/nkvknsSnfK6fme4FSOG0ZmB5nk7mL3k8gBzRlCuEJ65OvkTyIiqwtkHQRmh/ldNnNrBF3G9NnzUItzZcfl8UFNbb26aShY+nYKU7SQLw+y3q6xELIxpnCllpxqM4qlbztbg0o8f6ryZeEG7/4p +jRb1JIOIrB3kobE+ykMtlNhGSxTPKqrERCGq7AD31i0SAp1SIMAqlkZFBfTTW/lEbTaXkjllalkSvnA/kLq6OjnsnkZblqLlZbn1HkNjn7EjMKA/dj8nl+aa3wYrKB56QC/kpcSHS7XOwplmnS7qZnlZa936AnbE2ngyHSZkAhbyZnREHSDrZWEtnYJuFNravlYK76ojlOqhzPrtsKckToLwgEy6dEY8z0/ReZBy6qPwleCg/UC0nml/mJvnvnBJ -AkOt5P9mFZY/z41JZKpEifmzvnpIHA8knyQu9mirb0KQHNkSUT33BX3yCxKIOxrnAPGBS4wXaSv5K7MnzZr0o4t/nZvnafnJZySPlGHLzGzVGnx3mIbmW7mlvkmfmwxnjCEsIBcMS/dkdRF9UkthgNPnuvnoHligg1ChDdn19kZ8FvBZuG7qsbZhwT3KjJFBnzeEqTHJtSmuUF2SoL/ZomYu1Bxo49SSN2LdozhbRMTgRl5lYBXOGrQ7P6HPeCh8 +Xb0bllkGf/6pXnC8mEgkZXnyvk8gAXjnmxF6f4NzjEXl4ibdLT+qH6rnwVho7mVn6EvlWGL96LLDroBJNNkT/nTGmZV5/zFRjlVwJkD5nj4GtmtFqT0Gv6aSKnCxFsUaKwqV5HMm6FNoWLHN+4wHZ4XbjLroAWgxEuPlKDpU5BcWa4GlrpR8VpuSYyYzeQKMtKBTrlpibZnHXnQNkLVlnXkGnlOkysnmzlkU5nX/ml3m3/mH2SjyJ9nQTEBPMmn5 -mOwBzsm1yiS7njbzcB5GmlZXlFTFyPYpoHE2lgdQqJbePmDcE2LEcBHGiEeG5LgzVynRnTkJGCSlFflV/4O4Zapm5HnPC51WmD5KFeaglGb455OrIu69Fm1iQ4p5bRB/Lmpdkt9lWtmGgx7dmrrTMDS4abERzTIC7I45oHYbA33BmKQ95miPmgXmHXw+1yu/kUnmdAqGVRe/mXxk+/mSjnAYZ98IvcDqDFZaoRrgAVEYAUF9nGb7qfpEL7wsQ1Cb +DSA72nklXm9smeqGAIlDHKQJ5CTYSCrjrIj0rV+mBg7sZYs/77/4WJYVb6wEFWJmDC6GJD7hLO4C78RJLT3sJmIgtzphuAvIxHeiDWAl/mRSBl/kCtmmOALvk2dFmeGAnld/YQ7mhClQ7lZSSmUR3Zw36JmxSu3nrKAKgQFHFB/mtSYAukS/KsUbDHmeuxYewQ2L9zmwqRJ7A8t5dVGaKmXjQoqTY3Kd84bu7S+mVXo7DlZqmDC61jSHa6lBg6oR -+MbrIEjfmm2lCnmokK0BYUSQJKIXOEmGGsNiCflfQ4wSBMIHMAUuE5+0IO0AO5gFAXx2kEqZ8H65BwNDnNJbvw4gDbWSI5/bh6HE0HbMyj75o5ZaHzYjwBY4sPkkLmsKEGfT31mjXiQrrPIyaigM6bPCj3GCsSz7Ho0ARqfmsMFDVlZvmHfkoVn6AhgAXdTkFDHFvmQ3m1nnlAxbOr9gl3uSFuhPMl/wiDhzPbn3PnKXmAmDa1FlE6MDGINKPHnV +tCSmFK/0yhcLoCYueAW/n7/kJQrU/krfkCtlbTnBLnYrlUBBnRZwkC7nnwvmoTmsbmHnl+HnBTkZJAOAKVXI8/lPFkTUIxUGavmjmwAaDGrkeVEOt4uNnKflv2FwOKLHbYwah7GzNG/vnkfq6iEGbyjVHlBlTT4D24wzGevmT+6jTFyPbryI1THIAVsKF9vnbKLZCDpgDrqRiURTAwvaxw8T/pDcoDlOrwcmW/kZAXLfn/flOdm5AUMblJPZIC5b -UHdGGfsqCxFiK4aekc3kpHmHUyJzk65YsvhrODRiAkoCPMgjahc8TaOwNIHGbkL4R0YDJ7kHfnuAXRhS0znJtkLrm2n48AHd/l2lnlPl4Vb6OwSgw9rAHip0ymbBmGI4riCtzmxtgdkHevkLWrvSnlWki85BcFb+qP/k56o3dCP7mzzIRvQjjDOOqYAAsvj3yT3ixWtCueBdhzHcmhipPRJAAXTAXftlYxAd/mhKkFDGQAVXfnnbk3fmKPlq3lsT +fmWAXcnlhpkjIEYwGRqjNzkZCG5JSNtgC/lrZgtH57RmLIHaQ7mflLLGlyFSpwCTGjXnM+47eGIqFTjY4D5OKFYJ4bHGy1YY6nKu7xlz54yggXhgFmYHQXYdiyial9SoG27/AUiTHYAVkPTEgz3hiOzx6CwXLhodh6jgYEITKiYwAXLEL4RKKh43nabmV5n4Hk0AXdLnJ+np1EO5l0lmVnl4VaziCtsnntjIa7G6mGRJt/o/6APAUmASue5EWqdH -m8CzMsTKFjcTmayhgVJWQyIgW22gCvnfskkNF0IETaKRLbXuyH/RDFmg2ELc7hRGiZnws5gZGM9nQgHliH97E7HZoFEofY4xo5frjsYE3nIvn6DngQBM+BHTk3CgL0RSeQrgLFvi7I6a+lcpj+KAueCMADRWkpZjIthwPlEbS8Xn47l7blEfn5vnAikNhYcck4hkQHl1ZkwAWUflIXlBTmXThWeTTga7rkCZDPfANxkT/nATk7rgTdYs7nEDF8B6 +G48m8TYInm1VnGcGqSk/B5KxY9GHLy5nWkrV7/aEucmTZm7DneA4vixKGAsIKodg7I4F5ysGyAjRfNA6kwkfKyNkhfm6nlIPnrflVL4BHZYv6o1l0jks/kHnnjrlZXk8zk8tTdOSx5xaPnwJFLiI5zgLWAC/m2MlcYKkqZgw6wMHTHnwrFtSlPuz2TGxYrMrrYXY7Ab1q5NKn1Frtn7nNYY96P6ESflLXn3GGxsGSgVRAWgXnslhA2ZqVDiVRA2Y -NY6pebPsxLEJXllrHKorzW5xjRZivkobHu9EOIp6/nhvmTbmrmo2vRyW5mxDDXmSxTPKqrERCGq7AD31i0SAp1SIMBZlkZFBfTSOgU8XmBKgG7kFlmk/lj2lSOE+TlbXmOzl+gXQHl2vkjTn7EjMKA/dhHXl+aa3wYrKB56RCgUpcSHS7XOx7lmnS7qZnlZa936AnZiAWTpHh84ghaMvaPDHrp6xRGdfqjNEK2HqfQoZFt7ngQBWLQF5lqCAHNlz +ELBl6BYfIzs4L6lHegt0h5nk6bnwtmtdkYPnDulb1k0lkHikXznY4n89kV1Jzsq9DqnGF5Xnp1xT3w38C2Vkdzn6sFZbqo/kS/Idg5nOya/Ib7n6a76P4xAqxlkDtBmLQdgUTVBRArdgWfDC9gXNlkKGnARRIMClCDobArgiTTDvpAxLQRiBDGLbAXvWh7NnpgUkgWi9Bn/lf8mc75RCj4rkyTmmbk3HmsZDsxxwOReMmMgVfclj8rl8C/zgC/mL -PrtsKckToLwgEy6dEY8z0/ReZBy6qPwleCg/UCLXnwPnOgX0gWugV0zlAgUS1Gf/4XFnMzmVzmMvlK1kxXmAznmxF6f4NzjqSJpybdLT+qHNbmsfncnkRpD4Lbnnk+vljYIjNlzALatkAhbGXls5Fn6G55nkSG0iZnj6GenncaGLFOGGv6aSKnCxFsUaKwqV5HMm6FNoWLHN+4wHZ4XZFHmdTGgxHifnB5Brf49TGzbmjXirATU5CLmLnXBrpR8V +b4cgUXvrUpmjpZaLGmgpo4GUBZjqbqXK7V6Yr6SRn4krO04jXkMN59s7XbnCxYRBmL7lZ5bJkpnCmEfrjowPgWOJauWnRZm2Z5YqEAgXsJm8l6gz5IgXzAV+GL6zmgSFhTQRvQvWghuAYLBOPoioJOUn7miTbCH/l6AXH/nOHmZgWQvlKykFAVNdEHTkyHn4Pn3Xk8gBNZnhpnhczF+iXTmpWSD8io9wNAUtIx/jhinlgrFIo5njzCJJnyZitEgX -puSYyYzeQKMtKBTrlpiprmsLnR1nW7BtgX+GrX57Eyb05mEglbnk0/mYCgcznQJESCJ7jBPMmn5DSA4o3kxHlo3lxHkRpDrP7qpnAEppyzjrIj0rV+mBg7sZYs/77/4WJYVb6wEFWJmwfn37mt9ll/l59SmzA+yYhdBDshzXhxkRmIgtzphuAvIxHeiDWCNgVO/mDtnscTT3k2dFmeEFXld/b+HmhCmBHkxXnwplqEiAphnXalFnRsj8OIKgQFHG +lez7CGLC3Rb7ZD7z3tx3xCcORQpyVBCXsAIXnvWgDll7AWagVoXnetkb6L9CHrgUsbmbgW+Hm3HnXZljoBRbCFPbEzTDdmZOLU0gYpAngW5gE/tmlfrcanTmkG/Smd6tGHPgXDXkvvlfwy4elSgWDC64LBekBy1rnsJdboOWxwABLAR83S5ED7Xl+xgxXkivmagUFnkKrk4snCGxYXkmXkfDnXFmDkQL87bRjJLjHxhwBwribmE547AC/m4uQPB4 -RgXSLlEMlWyoz/mcY45eY8ZH6XnXXpmlLzU7Weme7A8t5dVGaKmXjQoqTY3Kd84bu7S+mVXrJLmnVkG/m8AVSHw/qlJsBaLm8MxKfhMOBIID8xxvaz4wroCYueB2gUPgUJQq0gV/AVicAAgV/tkfTlUBBnRZwkBx3msgWPvkXblJ3k7nm1zkZJAOAKVXJ8gW0lkTUIxUFs/lQQV6PntUABbI4AVn/nkT5y8I43mQlEX6GjLmh7GzNG02l5D6n3lK +KFmsxGQpZb5H6vk9GGBgbRGnZ54uz7sDKUZ6PLk40Ly/nJL4weEfjGD2G6CF3fmg9F4Ww/hpeK7UHFhrF2fmqpbNbY/zFUJGpp5sC7qfSIR57eHNZEch5h8l7BEw3kKemcHFeObMDFTZllV4lCCUEDtWA8fAUQnvbS4yiFFkXuKC/yIOidEBEgUyLkCtlqlnagUKq71HJM/nFAVXHmlAXGgWYCj83EGUw1nj3AUFbl8246apr4DFXkGPl8AWNAWb -pyjVHlBlTT4D24wzGD4YwpGjTEiAUSYpT+nkQVsKGF/mK+AI5kNzBMQWonnCVxlgDrqRiURTAwvaxw8T/pDcoDlOrwcn2gXdQVTAW9QUi9kCXmDQVJPZIC5+AWhQV7XlhpkjIEYwGRqiPLkZCG5JSNthCgVrZgtH57RmLIHaQ7qAWE5HstaOg6bQWEwU87nM+47eGIqFTjY4D5OKFYJ4bHGy1YY6mhPlvmlHmFZgiJ1aGbzQXYdiyiamRvl7zqXm +HTgeGydEkfz26nppYniavhoa8bP1ahencQwtG5BMZmrmrc4GSrniYIwk+rRN1xfJDX47t2LBrC1Go4wifIBPhkjXpWXAUAX43nxXmdLlkgX6bmDwoNXKnAVmXnQ7mjLkmNw8HS7HjPsl/CBaUQF8iHQW4vmoin8AX1H5lvlphEsozQ0ZQea5GZt5L4wX2fn4wVAerVWDfxBoyjfACDahaMQiAwHmxLdQdTiIOinm6SQUImT88BGAVEymkUHRfnUg -lPQV6TkDSRPXkHgXLvLKrk4fRCGReNB0gDoWB4WDaJDOa4KS5ebq7qRbPmS3krXlAHn5Pmy3nJ+np1EB5lggWI+kVPnWGkQRHAgYqojPfnJIBt/o/6AYwUmASue5EWqdHG48m8Tb1Xk5HnqYKQU6hqHHay9DbYuJz9YrV7/aEucmTZkwfmt3mo97TTR+9QHNkvixKGAsIKodg7I4F5ysGyAjSJFkimmWMFTrluAVzjGlNGMgUKq4l86tfnT5lyPm +WI+lVnkkrmASSTKrXAX2AVkMDZ/CWhRI/m02i6DkE0G/tnqtnONlDXmfAzY8mIuSj9nxoyjHmOv4FXRZ8H+fFS2GJESFKoRIJJTT+iBb7bVvDK1KMjDv8hZJjURCMwWelSaXlH/n/bmMnnoXklEHoVrMblMRmAVl1jl4XmMFmtTQnGKZTJ+/myoSwhjqLhB/nWkquAUmhIWmk/SlTHJAb6dnmw9E/nx8snCBkSR4mJlXzpZaajTI4WD0AAEfLmBJ -rrkKPnPvlKPnvpkBZnyRiz4B0fnwJFLiI5zgLWBCgW2MlcYKkqZgw6wMFmXmmnnOqZEZz2TGxYrMrrYXY7Ab1q5NKn1Frtn7nNYY96P6EcAVwfnNwVLybyGnrvk11kTqCxPmjXhK1olPwc5AnKKKfZumBbfIFxxJ8SiyLYWkL4TcFBj3k5PlFNkQLkx9lu/nDukHmKCH6Gfmszm7XllvlNLlxfzWBgGIGhgUKhhEzY7AWo3kPPno3n6sHG3mxgXJ +rUBw1L+cRa4B7/lvyDaoArnmzvkImSiTkQwVFnniWBrhoyvktqlyvlkQWMM4qDFo/A6wg0QUkIDHBi59k1gWe0gmPlk2anHbVWmdpGSCGMcqF9rhZi09SGWQHmw0wzxTTNCSo8TKEhi4x5jmpwWL1l/fmagUxNn4LnkgVhFp9M6eHlnxk1HmmXnBQXmXldFmy1R0JjFhRLkYLtxig7v2CiwVDlqK0Hxekx3r1WktDadtk8hrIJpacYa5bNroXQHj -Haisloxp7qxann6a76P4xArBnme6BmLS3wUT3G/s4PwUDtBRArBnlKvlQdBVQw6BhAVk3CjARRIMClCDobArgiTTDvpAxLQRiBDGLAwXvWiolDbPlCQU7ZmeHmQwXWbnn/Jt572bnyPm57mrwUmfm3LkAfRvvF4ZhhuYLtTl8C/zhCgWLb7GwUXvrUpmjpZaLGmgpo4GUBZjqbqXK7V6Yr6SRn4krO06VHlDMG+zaSukXukKzmyHbH6mI7Ix87IK +/m204a2n1Xqi/mvLxifm/sErJE9ST9ZkmcEi7ldhqzsEsDgsfmKjloZnxHpMBY9GGzCIpp7fgqufkzFkx0xzFnRB7RIyMgANIAvsByGB2AC5ZBxxCctRQMIbMTqgVeQW0bkjwWFnlkzpyqn+UledrmAVpWmwwVWAW3Fk1UAvfKA4qZ9mmxLTyKUiiiwVIrY0h7hX5fuIH8HpfK6jjxLRMGyl4AKAiaABCD5w8TWiwWzlXDlxZBorliDlS1FZwWjw -noLGVWlG2qrTFyzn7jrRZm2Z5YqGUwXsJm8l6gz4iTH0QUP0iGgUoCBlTnGbigSFhTQRvQvWghuAYLBOPoioJOUn7miTbBPgVOgXNgVLnmzwXUvlKynDQVNdFwLniHkILkyQU8gBNZnhpnhczF+joLmpWSD8io9zLQXqQXXHkr5S0HCXXlgrFIo5njzCJJnyZitEt3lVQXerqdcwyowYTnxYTRfQKS6QGZUiovazc6y5ED52Dda57sT5Nnh3ngwW +WQwU7SLQt6UrHhDkStnotng/n1HkcbnMln0nbo5otHlDqGrHB73kdzkooYe7H1gWFvy6Hmj1LhukUDEf9lTsnWd7ijZMJkZDxXfkkqTU2n9dLz+lALmaakLl4bplLaYwLkwQUHlJn3DrUCRZxeqgl4pGoSbZTjAwqVBIxFrZmsIVmjntLmyrmeTmV/k6gUf5m5MasenGXnLJnu/mS1mNeBOOoC1YnBzkDlflG9dHWeSM3kOnk+ijW7i1wXwkIjxm -+QX7PnG7lLdz9CFIIUJwUoIXYPllvl2rkUIhb/BTkk1DHU0gYpD4IW5gEbQVCeHcanTmkG/Smd6tGF0IUuPnHYH9pGdrm1iLxNmljB6tmaznqOZy1rnsJdboOWxwABLAR83S5EAZPl+xgiPm/AURwXt2AQXlKwXnqqICiiXkW7lRXm3flq3nFrm48gn4jHxhwBwribmE547BCgW4uQPB6eFmsxGQpZb5G8/kLOm43lFb5Q26556XyHaJZV2k05Hz +8Zmq56NMYTkxn64624pIWOLlXhH2NCiUBdACK8xioCbgA+Iat4DsADiUBM9lElmkHK5VDdhSyrmob56PmmrDyrAYXn1TaWBlBAl+IX1/mEfmBIU5bnsKAHhBh+isVl3/DlII8AVHQV4vnRIU3OTxQXKJ4mJG3Wl8tbvt76XpLg6+gZomYPuy6syF9rCfDR1AVCD5hCBtKbgDZAKrsTnIj9aps8kh9lN+ELgXtBjC64tdk0+TD2BUlklTT5wWU5mI -qGjpGKen1KlfjGD2G6CHQs72KGbYqH3ngjB7L5hrG6AWqpbNbaBPmWwVA2y1IUdjG7gXieF/RG/GIm1FSuojPlf3kPSZeObMDFTZm8wUHTmljD/3nw3zTXgJtALdSinSfhQfNLpECHxIXuKC/yIOidEBQIVT7kD5k5llzAXRwVXEqKrldlGSQXFOmACl+DZJgDn5zshjo7qAtlDpkMNzcEArIWITpwQVKLrvIU206p8z26nppYniavhoa8bP1ahe +MlkQXkuDpIgNrhKG7VVE23RBDbFA4QFlwlAJDLJYEG9miZlMrlxHk8B6B9Zxg4Hp45LnmLmyFkTpHWHGjDldnkSJ7Qhx6xmqFmtrrC3aL/nIgXJ8KvXSEQptWDV0wtCRLXyZrgynxLMRVtwAzl+Lnh9nuTnBCSYfk4h6vDmA4BXRGedkVnncwV4VZKEj1QTx/D/wgFvluYohYL3IVbKjiwVA8m1Pa5Ln31k4xlMq7SGnEpG6A5w84xMzPE470BfK -ncQwtG5BMbdbmrc4GSrnibXAXBbEhLAqvk8UQ+rRN1xfJDX47t2LBrC1Go4wifIBPhkjXpWXCCQWYoUoVmQbmKwWmrnKwWc74Pm7LwWgdmoIVbBDWAAPuo8HS7HjPsl/CBaUQF8jaPkffkrQVtllZfSPfr5b7e6KPe775Gi85THIrDleKZCoUsowKvR6NAHNm64i6ihFnimJArD4N14sAAvMhqAjLvaIOinm5gwURwUE7k4oXb4wk446oU2vkcgU +5QuT3Xpbzy+aEIOCHBJT1IwdnX1xWQWRgVez5N8wifCEgDMjB7ghO/iFyTzARb8R6gm+9rndkgwXEgU7IUorqq3H7IU1IUXsl3OnvCGLJm+IVBpmIvlmbk1NAhmirBlfPAguRy2lMjagmYxtkyIXTyI+wWFBxhzlUtlvLmDI79oFRGk/r4jsnzCp86o3qmxGlKjmb9kUDFera6g7BrGVtk+oVEBlgDka5m8Mao9gQMJPIwSUQU3IPyQueAqVAVPz -7nkubmASSTKrIwUcvlt8BUeGWhSIgW02hCTkE0GBgZg8l6tmg9GaFbY8mIuQTmkqQAIiE8QCOv4FXRZ8H+fFS2GJERKvlCkBDXnl/kRIJJTT+iBb7bVvDK1KMjDv8hZJjURChoWelSaQDPgU6IUeHnsLmJIUL/wMw6wwUSXlBHkaFmtTQnGKZTKhgWyoSwhjqLgJQUfLlmlTEvopQWc0ZydF3b63fxi4LDrIL9pOuKpsE4xl+DET3L3tZKvkx0CD +JFCOIUrPHZ3mbQTlIVF1SA2BYoW7TlAXoyxl6oUcnn+IWujlbBB3yCGAS04hKszIwWpAhCgRLHBUoWIoYkNkb9kCb4RLbW1GplELPmnvbBQraCrbez9GxnDwP8iBiqrlo/JBqGCBJJlqklIWAuBlIV1n6qoWTSD6nljwVyVrlzlJTw+IUNIX6oV5oUOwVXWzZSQgiquRCl8D1lZ45gq4Aavkd7kxxmeqFUmLf57tMnouGnWmDbHTl4gyY4zlHoVw -nk8UTboA0jB7ogl6AEfLmBJrUBw1L+cRa4D3gVvyDaoA/AVE/kImSWzmiQXBRqcXaU/ktqnU/lI+mYCg3PG1cRB7Y6wg2IUkIDHBgRDmRAW+Lmjmye0gBzlk2Z73no1mdpE7QXNSzRPkNzCnoWZCraxoBeBpnTZJjiTHNCSo8TKEhi4yNTlPoWdFLhoVvoWMtnuDlz7nS5DKRK8dnm7mYPlQHm1NlIXl3Fmy1R0JjFhRLkYLtxig7v2CZoVDlqK0 +qkioVeVlez4RvTPtDxABMBKAZAwBBV0jxLRKUBQkijh45knqeRtLnorl4tRT4AnHm0AXGRmoawBQWNIVDLlbgVGoXyHmBda5exa5gCzkAvKlMSVoWy7byIUACqoFGewE0xlVtl1NmRjljinvmnDAWyHY2g4n4mruxzhJNmmGQUmHaZtlmhD726il7hVFZi4lhmjnmDC66QxkRxEfZhTSV6Avix+TyiZIi7ww1JR+ks/TV2A+DkZVgBLl4tSTuBfo -Hxekx3r1WktDZ43l457+vYa5bNroXQHSZnfgoMnH1XraNEnSnnLw7mFbZ4sAVNdw9Hl9eJcBG2Q5DzHq2GiIXJdFbd4qkazCIpp5iYXrW5vPkPuzPrk2mnB5BkSx4gVMljRIyMgANIAvsByGB2AC5ZBxxCctRQMIbMRhwUDIVp7mkYUlbnfJobEHyqledrBQVpWnjoUxXkUlk1UAvfKA4ohDmmxLTyKUiiZoVIrY0h7hX5fuII/l3EGgQkRX4e3k +VjoU/qGb1ldyzyQV2wVbVlKQWsZAsjApWxEFARtnb3mY2lsTg84Tv/kZjho7lNfjunwwYXyuhEbamjFZ2k9KZnQ5Iqk9Vlx7kCe76jFSREydEUqnSdHBpH25zYFEp546tnxDw8B77BGhBm7mnhuE4Ko/Nk2YU6/krRpXwjI6Dbeh3sDg167lHwWA3sAfwBMYUHnALFjoGopoVDoUaLgpXBcYXcIUfgx2FkllJ/oUzoVNIUe/mduAz+RYHLHiBs2G -iyzpfK6jjxLRMGyl4AKAiaABCD5w8TWiwlLn2DkOTnTrmtTmP1QFigg3kaoXyJnq6mxhzfoUM5mIMl/oU8gAF7nOln0nbo5pyXlDqGrHCAD6tzkooYe7EogV09JiZb/74MslJLmwqmCbnWd7ijZMJkZDzHAW/uTU2n9dLz+nOUFVXkH/kLl4bplLaYyrnPQUk5ANIUiJDQwItSR9rmEDzrUCRZxeqgl4pGoSbZTjAwqVBIxFrZm5YUFzn5YX/TQg +r1EJSC4FQ7oonflRIX7Jm5w6RNFfzlil4gukXvxfsrYXYnmmdDm4LquNmWwETNka26Czoz+EZpogUqLkHI9G6g69gHDNEbrEwjkcHHTel9QUuN7BuBMSCmP59balBinUAiKhsdzJ/w6ITZnnMYWNBi+YXvkSpoUfoUSDlVIVN5imTK/wlBD7HIVMAWkQXxZZhKApWw6FiRiEZTFF+DEVjtaT3IUj5SxIU06q5Q5YYZMm7FZ5+jZLbRN2ZtbmaCG0 -UhFYXQbn4xBlbkhSawNG+Tlm+m0YUBTn6oXr7k80BA0j2hpRjkc3zWeR3Pn7wXKXkb3iVXbtYWZ27Y7YpoaNMYTkxn64627A4V1IWDAwKlm/TxUjmJXS3iyIBC5BBk3iPnSZrgilyt4DsADiUD2TlGlmkHK5VDdhQnYWob5MfmmrDyrCQfziQWwLnS9m0nnxVmSHmwHnsKAHhBh+hpVl3/DlIKqQUsfmOIVsfnrcF2mQQe7mhIFNbBvmDW4EwY51 +aLLLlJ1lHp5b+lWLrSVHau5iLaMvat9EWLqx8qteyjiSPmnBjFV2nAl5cZqQWl/Hbx572fkF5avWax8rAVEKumDZnRpHNrrXBZz27gAVL9aIj4qT4S+mCKpc8AA4XvYVNrbU/yy+KDtkIspfunxjQDgG+bl9VnPvwzEFMrSGWQBeAeSSmJAOkBhoJ8gAy6ktLkINBvoXsIVt8CefzqoXVIWTYUS1FKrkaZ4RLklAWKQVlAVtxAkEgFXbvlF7HADU -ryLnppm+gac+rYgVkSyeoU3CjCfDR1AVCD5hCBtKbgDZAKrsTnIj9arB9mwFlN+FywV4tRDeDR9k0+TD2BWlklTTlYVSQUL3lmIXkuDpIgNrhKG7VVE23RBDbFA4tYUgKrZoW5KHpjlEbk7TmiDnIrkKRGCYXbqlrhmN6l0H4Bbna2ljDmVDlpV5JQlgUHQhx6xl+FmtrrC3YK74oTm83bUXnjyAHNlNDCq4gbghpuJ/xxLXyZrgynxLMRVtxMLl +aDbCTKo4vmFRkf/lboWFzjf/mthLxIV4Q6JIWhsH2xAoFkTF5dB60fwH64IwkwOhmtz3+zuaD3iwo1A3yT4QAegy8oDkbm0znUOJsIUYoVMuAZoXe2kBWSX/m0KkACm5inZoIPXBuj7DWbcEADUbP8A0WmewX+jmNugDeCxTlmTkTznG1laiq6p7zsGjrEjNmJ4G6r7TLqF9rSUCrODEK6WBLZ4Bl0g5xwkIycyBe/heYWyfASCisYX+LmuIVF1Q -TrlHYXgbmK4VfYBRwWnUpnLlbzyWBnUYXbXl3YV57lXWxKEj1QTx/D/wiB/luYohYIm4WVjaHAUWfrHhk8rlNFlkqkRkFw84xMzPE470BfK5QuT3XoZ4UeDGGaCHBJT1JLdnX1y4emuwW+IVZukhiSv+wdiQHNlN8wifCEgDMjB7ghO/iFyTzARb8R6gm+9oj9nKoV47kaLj/CzK4V44WmTIMmawbkGgHjIU0YU9gV0YWbhAhmirBlfPB+lkFGFM +tbD64Wur6oGFG4VFOkm4XHikDUIvzotJzoPICwVvtmhT4D4A2jg9IUYwUTawC4UypF6/ZlSGLmGtZGv7GV061SF8C6cFZONnMC5dAVAWkengudADEa77lOrlmIWc/yPMhdWAAKwSxJqGBk7Z31hUrxef5S6bYwmDwVsYVx4WjYV0/lWwU3FEy+r+skrQX7nnxrmgblGoXI5Hdsa2onN6bXIWxXp1cTQVkbYXKORObkWJl1hFFz78UEjzFPZHdTFw -jagmZSdkQYW8vk+ijTyJYHky2q194HtkSum4dEkhGnb5GhFBg7YxnXmkm2kAu6xGkaTnDgzxBnFjkUDHBrGWdk/4VRBnRYVZUoJzmoYVERZyaxBoIsAAMXyXDw7cpU9Ao1CwTY98xlqkO/mbQRY4VF1SA2BmvkVo4o3qLJkYPnZ4W74X3YVkuB3yCGAS04hKswmoWpAhCgRLHAm4WIoYFIZ9zkerbMVnW1E3nl/grS7ldrnBFkvICa3oYTnaCrbe +KkosaPYVIsGGbzjFl2+qoBnG5z4xIiC7N36YYW4VzXPkY4UVLmt7wbK6Z/IfJCbAAYTSDzzfNDroiyUC+mDzWx7sl7zkDoUeyD+YW89RXODU4UTYWH3nrC528LXXnGbkbgX2wVCIUFoVBmFYiZv7iXJKvXnMmBQNCeuYMQXmsjY7FuinG4bPA6ijakL6lYXEhDCGm0hkS2EoGkYnHXfns3buGGHlmRLZ0NYsHnmsmQRqbmgmIgRIxR8BAQBgAIEL -z9GxnDwP8iBiqrlo/JBqGCBJJlqno4WAuCY4V1n7tBijYRnYXkYUfgwy1kmJpMzlY/Hz3mmIVVYXZSQgiquRCl8D1lZ45gq4Cs/mcnlWoWeqFUmLf57tMnouGnWmDbHTl4gyaKLlmEVwqm94UPnn94VWiqvzxVQ7OVk/wVj3iUEBMBKAZAwBBV0jxLRKUBQkijh45knqeRmbltTmYIpSEVga6mVHb4V4EWTIXxoWuGCxWjEVmHjH+WQ5zCtMIAvK +AV4BGZLlFnbFniXDuJz0QW/nSjYRBYU5wV58lV5qnZkqLkCIVRLmAYWuGA+pBkvAgDAZgSCwXMuhZuSF4V84WyYUC4WTywE+mm9LfnlIfT/FkBfbg56e1EihBtQWgHajL56YEm2lwAx/NkIwmVtzx2DkPxoMAvjxbOD0xonODWzFjTARRkzVkgEW1w6T7z/Cx7IU04XQEWKLmmyGcwUczmIEVIvlCdgsBK0QRzukhnCkonngB/tiEvEbYVJkYMHm -lMRUEWy7a/YWoNoGk6b+k7TlWdkaskZTljinvmnnQWyHY2g4n4mruxzhJNmmlIUmHaadnm8D726il7hVFZi4lhnO3mWQXLtbLYVKrk3Ci6QxkRxEfZhTSV6Avix+TyiZIi7ww1JR+ks/TV2D5zl/agzrl4tSTuCBEUXsnjVmoHHyEXC8ma4VKEXxZYsjApWxEFBjbCnHnAqgQTBChbvfmWZHs/lX4X46DQGkhs6mjFZ2k9KZnQ7FVn2tlQnk36Fd +6TlMHkDGkv4U2mmymxtwxSxR1vALAC2CjZCDfvpPTR4MBRGLYwlpgX8EXRloPATgEXiXgLQUwEUiP4wwWzwVfMQBQIzul17Kg4C54U5yk8kZ8hixEWTvD9T6N4VE5HpPzqjGWvkm1GOvkrL6yZnILH45FSZavSmrLHaFGn3l1imF7b5satvCPfj7UByAhE8DXOguNCxgb9wWbem5nlFEX2HLb3hE6oiEWxczxJa+JDKLkGgWjrlGgWL4WyEXLSkM -Mm87Ew54UqnSdHBpH25zYFE4dmmAXqsnaDn4BiZF5hBnhuE4KpU+lZLFCoUZWBZKSvnlXwjI6Dbeh3sDg167lHwWA3sAfwC9EUHnALFjoGqoEXiEXL4UuYbDIXFYVyVpnLk+9FjoVMvlfMQz+RYHLHiBs2Gr1EJSC4FQ7op7wVqQUHwUaQVnYCsQbfLmJBmVeo5N4EuJfsrYXYnmktjm4LpotmWwGOtka26Czoz+EZpogUqLkHI9G6g69gHDNEbr +0pSgw2hjKHlzBGq/Qe5SNngbYUeZSYplZunhqGTYY47ZNdyuG5zzkNhrAaqQXa+3maZktzZGhmee66plho67BGLXkUxkTTGG1En9kMIrqtZJQX0tmBvm8MYuwpsACaQoF9SO2zxSJvvwLASkAAGNLaBHuCml5lj4XvoVCEWguDeEVQEUVo4o3r1IU/hnYXkzwWY1lZSSCfDrvx0HAu3l0ymOaFzmTz5G3EXPNxX1mBOlcBHPZFe4V7/65Z6LsHRB -Hl3kcHHTelgoUfCQI5kPZDEBn9QAHNnBuBMSCmP59balBinUAiKhsdzJ/w6ISvVnR+mNBgQkXvkRoEWK4W9DCq3Eq4X44UN/RBD4a4VEoW5inZoJhKApWw6FiRiEZTFF+DEVjtaQtYUj5QwYWieK5Q5YYZMm7FZ5+jZLbRN2YUHmaCG0aKo1nsDlHp5b+lWLrSVHau5iLZrgWxLy78FHVatrkxH76xkC+nLL6+HlMd5WzzoHbx556AUF5avWax8r +4ZkSjjBumjHuI1Ry+VLU5BiLiPXCtnI5kncwLk4UYoWcYWjoXBYUSvqHjn8YWbVnedks4XCYUV3nVAzHTCWsRPMnf7A0yaRIW8AV9IVTFRJu7xEWWPT/T6ALZx2nDIUHywtDle+kibbMDkx6EKGmmAAkIyYABMqS6CRKurJkRP3DIMCvIroyn0gwkjpDYWDoWQBilEVkVn0/nE3kxVbdmE3XkBTlzYVEoUwhlV773OQ85Y2XmxXpQeJNn4yIVUfg -AVEKumDZnRpHNrrXBZz25kD7Vb6Ij4qT4S+mCKpc8AJkXAl4YPo8FYYwK0WGCOnQ5kIspfuk37kM1kQMCcFlovlGgVL4KDshMrSGWQBeAeSSmJAOkBhoJ8gAy6kgbkINB+EUFYWefzqkVr4XNvnNuEYFnlbmxoVYPlTIU1NAkEgFXbvlF7HADUaDbCTKprEUNDEbEVTFQ7HCAVFe+kqlaQLb8FIPe6WVqba60fwH65CoVaOIcH6aLmSnxXIhERwH +LLm6vr90HnBHqT7AQUzpkifl0oUDnlwQpEBHObkSAV4bYU8lRLaSjLegAAjS6+BERx0OTHeJZ2BEcllMxoOwirJlkDikWP1TC4SJ4WYcF4niz4V+xlSEUGoUyEXaOzShnp8aPYksPCWgWPzl54jRZDLNYRdh5NkXYhbklHvl9Gk8Jyu8m2Nkv2KFDkkjEt+7xalJZnjMkq25NUFIZneBAut51Jl9AUsHE7pk/VnC6qjjD+NC3OjQBBoMDxrzgmJk -ADkhYo1A3yT4QAegy8oAJ7lmLnUOJmznHYVF1RMuCYEVUKk2CzfgUKEVU/mVYWzEUxLFW1pmeiSfEDUbP8A0WkLoVoHlRAXgDCnJYdzmVDkQrln1laiq6p7zsGjrG2tmJ4G6r7TLrYgVAbz+tmjXjSUCrODEK6WBLZ4Bl0g5xwkIycyBe/igkWyfASCgDEVOTn+EUtbDPkWvNnfDztpldgWQHn4EW54VbBAvzotJzoPIpoVddmhT4D4A2jh04WWo +aigpLBSw1kXAwW1ZTFEUbEVXvB4kUH5i+EW3iRg/6M4WrQXM4XrQXaOxEPkwQ4GVo4BgXEVQqJTKEnNkbYUvJYQRbkhkfHZsNRL15uZF0tldOljzmWeqIiGXnq4aIVKlR3m/znyj5Zc5qwWlNay6GSeHe0ZJHmjfl5UZTcwG+AKqDCoKn1SO4BCrqBgD5Ji91C7HnukVVvIXxIxkDrEWyrni5IeIX+Gr4V64PmyvmnIXzYUDhmZJZ9EACCGWgWse -UM4XQQVMYK6RqR/lWf6LHYwUWtZGv7GV061SF8C6cFbItnMC6CUVAWkengudADEb6nnjbk8wX8kVKNnInkCwVZOw2ua/ayD/pqGBk7Z31hUrxef5S6bYwlEYV5YVJ4W/nRLeEUUV5+wyhF3zSpIU57my9lJwWsZCHxISgxe8LN6YG4WxXp1cRGVkWkXKOSH7mwtm+zITsHDW5oJphIrPHmQsp5ClaT4cvTRBltCZJ5Z28Q/7FmbT4xIiC7N34FEW +5BByHTAAUXTdD3TnvSkVhFQTEUeyEqqOq7L9bwaqQsr97mMEVez4eqjOkByIBE0QVqFz3rp2DzXx5WKzs6P8lQ1mlIWgEXekVS1Eu27jYX3kXzbm3lFUgWBEWCYWKkVGoV+dnEIgsn6IYA6h7RsjmZJboAZZgbYVGAgibmfF4nxEsXlTzEDPI3LmGiGLGail7g5kFwr5dn7SbAtGY9l31FQkVYUW8MYgZAYyglgAZlT08rh1BVyLqACPhhkagg2l -4VzDfkVkUvrlyrkP7kd7ngEWksZmtxkRB/DQYTSDzzfNDroiyUC+mDzWx7slcXmQkWQBi89RXOB9kVN5jr4WG9FaoVZqiwXltenQAVhEV2UXjkXL3mgBZv7iXJK6wWuMAC7giuYOIX4kVOIU6V64KY4jFr/4V5kh3I5NogN4UjFxEac+l7IUTJysN4ibFhnrwQU6QWSgXMKZmAWC1qHUwOXnZRiQRqbmgmIgRIxR8BAQBgAIELAV4BGZLbFkprm1 +6aRDeAx4XooX1kXYUB3kUHIUPdm4mQp4VKJn3tlFgU5Sz0jB+fh51QpwSCwV8HAguhLwUboUPQnDFRPsG3bE4pnvEVCtGkYF1UUSFK75GH4U93n6XqyAXH4V0I7zckckVskWvZGeVlkYVEJ6BgDM9KyyxJ2CxwXOTbRDhr0SfMgP9BukWk9FOHAntkLvHUUXx4U+1y6UXpUUghk23kzYXFOmACl+DYKmxA3JZFTeoBF9G96AHth24XZrmXZg9jmD -ZTRloPATlUWTSCwkXnYUnK52j71UVnxm/gVGfmwAUMUW4Pn4eogDAZgSpoWjZg4BhZuScUXrEW6EXdFSTywE+mm9LV3lIfSWiriDnFpoBfZLTE6crA0UnAWjvkZ1pvEWyOofEUNtkzPk8USVtzx2DkPxoMAvjxbOD0xonODWzFjTARRnC1mlUWT7wr4WVUUH5gDkUlaGo14jkU54V6oWEEVW+mumwShgxOgiNnS4B/tiEvEWkVJkadnldYXdnkDG +r4dMmMMJonnMPlDspGipj2rtObenkqFYHYVdrRKKkglkvjHlsDXrnn5Fgtivax6JAL+hdWA2FxsvhkyRwWbXXDffkYymOpqUUUCEUlEVcZiqrjlEWItZmDrNml4fmpRnXHlCYVGoWZRkRTYXkiH2guumVQGBr4sFD3IVhpi2oUFsrIFFX4VoJpkqkMHGtBlEp6eaGl2lNX51BmNXnETo5eGby5JkVskU94amJn3aHOXYH4W4plLaabrEqhZRlaeZ -lJUWGYUP0gn+AmYWXwhtwxSxR1vALAC2CjZCDfvpPTR4MBRGLYwkt0gXxIxkD2HLb3jN0TmUViplBmkT2nE4VlPnqwV4VYBQIzul17Kg4CsUU5yk8kZ8his0WTvD9T7SUVE5HpPzqjH3VDFukJ7EW4ZdfrC7H5CH5Dl7EVfP6vSmrLHaFHtvl1ikgEUPZCC4WjXipcBV3xL6SVCA0HSrQIz4Dp8CT4SrqQEYWbekS3niXDuJz2IWmUVNcCjEWmaH +FNXkFLBalY+RE/G6mYXNga3hzTk4dTEofbf6HGiFDwbibnQSB00VyvSeVHbnKy0X+9Ed4XPvzXfjFyIwBCINxnKSXyRR1AcvjlRpnlTiJnxinTQWg0XXkU0UVhPl+kU3lE+xkYJlAbltkWzoVIEVkuC1FEeNqHkTlgXpOIc8KCaGH3J27kmylboWekmOUVasIIFniZn3nlL57LHIVZG/mkDDGZHao97ZdaoAUpSFtZGbkWSFmrkWtKnYFG0IHXN5 -qHEyPk6kUACl6kUDUIaIiiPrMHCDZCYkUAcge5SNngWkUeZSYpkD4WhrGlZ4oK6Dl7KpF+Spu16A5rCjKhrmjL5z/nUAXNDmF2mpk58rFmZajiFGa4WIFFGqbIUSxFi86goV94XgoXYwZtTCewUcrIilyaQoF9SO2zxSJvvwLASkAAGNLaBHuCk95mJ4XmbmFbmrIK44VVUVk0V05aRyZE4WlPm2NkVHHKEUsvnvKYAxjsvmwgWndxHXijOQWoW/ +/6aE77h0zWgr6TaJ0UHUJ8snxW5OGFDw5VTEosBS/kvn6STb3VC99leHGhe7LuETHmUZwDT5ItzjNk1CldbG4HTBBlmrT2KmIkJaHbEqLyalQexz/alYw64aR8zAXnyAVEJ43whl0irEQ9ExARTlrAs1GqmZIWBz0YrWwaXnuEUjYVCEVb6RswUNmnip5dlGMAXrUWm4UZ4WwxnjCGB8xYSnpOLgxKPbDIKiqEUNDEEUnu0V+5ZH3kGxmkSlVPl0 -UXcUV6Pk6OGIRGKMFuEGBOlKYXop4Vfl30UgEVAbzu4XI0UDlY3Cp9dyvOhEajo8QOsKvbQlRi4ahhZEHGnDCDdkX/TQjEVXUXSEUSvoq0XWUUy9l0nmIXn74XaymXKTz6CWsRPMnf7A0yYfYV4kVfYX4GAcrk06k6LGWGb5Oqeill0V4Q7hoELFGq57+vk1fltn6kjn7KkjHnV5FJ2mWAUOgxmACcI4Z3S6CRKurJkRP3DIMCvIroykxtmnORT4 +SmY56ZpKfuaVykJ2nKjlE0GTjbG4bjdEzAUlDYIgXG4boJGIqHlylWvFgkUlWxPugWcFy0Wn0VSvTvCY0BHfT6GDkTa4YlEdrLKbw5fmcKZcpJUIoRDHPxR01EgW5mjEYwKUSznRRP3khzSUSkUZTDjZDfQ+VxvUUsonZSQeNBdwwTPqRBSaR5YaiG+BlcCa4Vt6DMzmekWaUWeEUopAz0WbTLOlZVEVkkXHViTYDOCoX0QcAU0kUEdppKCSdjY0 -CE0XAMVTWCp4WHPlBLoir40UW+gVNUUwMWduCsvgKF73OQ85auJxxGpQeJNn4X4UNvndFTMMnRwa+RHXZFcVb90EvZEOyoYK5J/Yc4WBcEKEAqEYEBHLUV6gXGjnBFnP+DrUUCZLegAAjS6+BERx0OTHeJZ2BEcllMxoOwirJlkBAMWPkWeQVRoVyFqdviQMUk4XggU53Z5nSS0G27AsPAZwVMrl54jRZDLNYRdiLoV4XkXYhbklY3l9Gk8Jyu8k +XToAJkVx8FX9EkEV0EWzamWGYq3kTTkSABYCylhYZrAgHycUJ1wpXaRy4xrqTedzehlRjqGAVT4B+YVaUWU4XZiA0MXH3g35LLQWtkXTwVBQUMMUhEW7fm1cRjpQGKIQE71fQwfCHfzY0V9pYtH6JekKCHAUXwMX1Tk4CTcQG9mrEBmo0KAOwtj6+0IQ3njbw+gVStaw57xT4OERP2ESOl7wU94ZydEgdkeE5g3nnvkX5asNjJekSJLchou1CxMW -QBEdrnzWGg7lEa7xalJZnjMkq25NUFIZneBAut51JlHQXk5Gpsm1EVuwU3nkLLkd3mjXjICb+NC3OjQBBoMDxrzgmJkaigpLBSxOMVKoWnUXy0XY4WugVSFik0VbNyigYuIm8LnY4kkDkV1JNGrIi4GVpfUVLRkzaDGAieRE/UULkV/UVTFQvJYQRbkhmTPlvin1z5uZEntldOlgrmWeqIiGXnq4aIVKmyvl8rnyj5Zc7VoWlNay6GSeHe0YUXkd +EaRz35NyFFoqkKGXO4ZBkCs5lunQe5DMAX1assBLlGizYn0V/bHdUWg8lBgUf5aJzlcQVlV624AGwBKaSwxCHa60czFviRxBgxA+QJv+lvyANy5wpBzUW2XD/TQTfyQEV6UXE0bSDHYN6VzkDLmW0WRYUBIWbhAhq4jOxDZCXCzH1mpAFxvrlUXpDmpVD7IDL1bQObSCGDkFsHGEJE9mJM+kmSE4lr9pEg5nmQVD1mQoUdEytHBxYQcvgd6h5+L2 -AVUXmF0XyCCX0H7Nkox6wDJ6I7dmRfgSs5DIbCEDxiTwF4C1pGP8lVvKy0VR0XnUVS1Hi5IfoW4NwX76WrnWvmjkXhEXaOwDhmZJZ9EACCEZwWse5BByHTAWkXQPCH7kpF4+UXAmmPwqEqqOq7L9bwapBUVw0UrUUxuE+DT80VOqgeqjOkByIBE0QVqFz3rp2DzXx5WKzs6P8kR1kY4UeyBQkW89T7T4k0Wq4Vz8nmrlRspIkX/gXHViRBQ1lapP +mBqJzznA+pAqfgF7kpZgDfCzUVUUXtMVpoVIsBSkWiEV0nrXTa+xlJVmDMUAYWI0WyEUc/m/XhzWCZrnYUkCQiipQpYXakWYwU+igqWie0XqVKfNktXn6cYqJ6MHkMTnEqC2flfoKLYG/FmCY6u6nJr6R0W+hqgLnQzFIJ4Kdmpsl9UVez6pKzaCRlvDPf5apJtWDZBBpYQfbxrJqRylOih1kUdMWKvZLUWaoU5gV6gX9MWxrnz4UI0UmUWyEVe/ -GzGaIHmGGLmoQoVS4kX04V9UWM4U98gnEG53n5h6ZXp2Iy/GJgl6LGail6Q5kFwqO9n7SbAtGf9l31FhvmnMURvltwVTPlQoWjXggZAYyglgAZlT08rh1BVyLqACPhhkagg2l6aRK4UuMWK4WeAUx5gdMWz9kK3ndmEb0X1LkzEWa0X3fl/8F51QpwQfUV8HAgujMYU6EVn0Vtlk98hPsG3bE4pkNhqeZEVGFTplwyEa3p15BU1FPZGm64deLX7n +mXTgrDJ2UVvNEKhkd7DYP7Y0Xkhj6kVOVms0ULGa2Lm55KEqKH6kpr4y7Es7kOZLrp71OYVGHqLG9DHXMp4aKqLGUJGHBm8UGhgWnEnWQVEJ5hoK2FyYwA8ljB5zfvrrARyay9VpLPaksEKmIG0XzUUcYVwVYMsW04UNJF5rpPdkGVm6MWrvkN/kFoVN/maHSQ7BrxgSFGAiioMRCsVZ/GFNkFz5IyGZPkdXlpV7JrFDEa666N/xnFbRsVYAWK0V -ata5Z4vZE30UKJrIUX4sDP0XxYXCWnqKqyyxJ2D0ABNHDqna5rjw8QvfjCmHeWyrSRwpALvEtMWuMWzwUakXVUWkfni+a5rlK3kJ3lPvmiMVtxAKmxA3JZFTeoBF9G96AHthAUVKXmYAWXZiouEhr40Jm1TDmhGSK70zSiblUwUXvz8KwOkVdrRKKn8lkvjHlsDMEX1IVpLkd7lasVIe7eaDDsiWAZdWA2FxsvhkyRwWbXXCfAVjtGnYVlsVy0W2 +d/ylOym+RJwFwIAfpgnsAo9jGkwaaHz1ldCT6AjKMXDYVgEUQ0U+QXnXlV/kFn4otlz4WGgUL4Vs/k8gBAAHB2QO0XE/Fz1YSdhHBBCsWbcGH0XeVGqYWS5maDKvgX+bHFZ6qDYKFaKdmR8x+jHaTY5y63dCOoXZc6jMFPunenw4/7y+mZ9ybnAoEIM9AaACdNI9jLy4ADAAimnqblCvk64X1kViSBdMXLUV0AUMaEssUaNlssVrQVHEXaOyYTke -XDAMWqrjuMXZuCTuZJ0VHiktYkDBJrG5nfoXkiH2guumVQGBr4sFAtYVhpg34VeMpqSHBblTAEt+7Nq6tBlEp6eaGl2lNX51BlyU5/bk5eGby7qMXwUVa6Z53lugH3aHOXZFz7C9FLYEetlgcXOPnhsXbqExYpFybPXYwLHGAXx7G3hzTk4dTEofbf6GyAWUQWN7k7h5QXaUKGeVHbnJUcX+9HzYWM1n8wXEQDsEVCAJ09AvaQYjI5rCygCBuDJ2 +KgdEZdbAXEXTSaFugWZK84W70XETm0Amu8w0Pk06keinMHk7mlLTG2YWbYoUIFMVofB7zqlL/bkEU4WHUEXaQ4BoWzPmyCq1xGPVDw948E5qFlS0WAIUKGn0IDfFDbsT3BLaiisSzVABIBDgmK96hqXlYHlankuIXYkXDoXhHhAEQ35Avk6zTiPHoxrn7sXlsXssVvkUd7xSiJIPCOUDlwUUIiN3iE3Q4EUgkSDTb5b5KFmglkLpqJaxQsUBvnBU -Cs5BsSh9bYrWzooUfMVnUUK0XkUV8MW/QYrgYYJlQAUszm6oUZIV54UD/l01xyBhtrC/dkYjnA3iCaGH3KXHl+sV6EWekm17k0MJMFniZn43lL57LHIVZG/mkDDGZHao97ZdakcWAel/sF5MVpAYQ9k5LEFhFEBK7OGK9ZbCHh0zWgr6TaE779Pl7oVF64KlEYQWpfoJuFBfYfS6STb3VDVDleHGhe7LuGoQWBtFBOltJKK/l/qmcwWAjDBBlmrT +Xkkqam52rB5JgEyAc5AlyIwwRzQw3qFO/gJ/HHiTDCC0sVpoVIHxQ0XBtaDzKtzI7SQL8luMH4oW3XmtqlEoUVAWxOAlFilFSloWsdADLjfJjowVqEXQMRo7moPwB5louHKkn8jlOIZc0WkUxycUTzJbIan1rWcWpPIZkX2YWuYgsBJ5Rg33D/4yaokUujd8ypbJFOyKfixvmmwUT0X5sVt8D7T5PMXbEUHXzhrIL0Vp4UtYkDBLV9RKN5UpT8QC -2KmIkJaHbEqLyalQexz/alYw64aR8zN3kWQVFMVWLTzWmChB9rmaJqrEQ9ExARTlrAs1GqmZIWBz0Z8cUlUXKkW0sVcZixuAXsUWgLip4EoUbnkfkXSQXKEXwAVstjCRjOUWywzgxKPbDIKgTMVk4mQUBUFnolS6OHJEWWPQsv4Cb6UtZyYXXOG8UE8UE5gSOoXH+aqMU15bG4bjdE1TGbaYG25i5bNPauWnlylWvGLDmkSmrHyEaJ0SlRg6ZAUk +qvndqqGRgapgQFmhwZvNlXEFIkn4BK7OxR8wLTG7XRLRHIRYwrEy3kYrTaPZYwp5PndGFrM6LPlEgaa/LY76K+GL7mHCk/sWOuKqWrxukEaIevlFLFO053syP4VSsF7HHv86Ff6FfkVLGF7b24CGMTRqaDbYhxBifAU3I/ayPyCYHmxlAvlnWsX3MW2sXgwVcIXPMVs2rZS6lsU6MUkkV6MV1HkFoVwznhJk0WboSaRQXO7G9wjEzR5NmZpzMXKK -PqaXmk+ATa4YlEdrLKbzxAWcKZcpJUIoRDHPxR01EgW5mjEYwKUSznRQjvkhzSUSkUZTDjZDfQ+VyLsXg4UHgVM+B3WmeCAHNnZSQeNBdwwTPqRBSaR5YaiG+BlcA3kVt6A2LlKkViEVlUV1cWkrnDoUb6LOlassUhjkMUWBAX2oEX0QTEAgYXtlBpKCSdjvsXToD4blx8FX9EMkU2IZstbWXmVkVJCDyrndsBmMU8URYCylhYZrAgHycUJ1wpXa +YX1Y571opxbSsnDJGsfkdDGYBkrOEm8FIpZGV662lDEH9fmCYK0XmaWqafkSl5y85IE4E1YtcU07kxNqUib4/7195EDYbV6A8VdqJ3UXzrGbHHjXnst7a/mAcXPC7T+GXwXV97ZxkTQZGYZzi69vlJznaH4sUKiVwDKSr6RhqTedwNDRcvjH+ItTi6BkrcEikAUMUeEUdMU6TD2sUPkWkzFBLqHwaMUUFwXMUVEoWmgXzKAzfBeEJF9F+QBpKBE1 -Ry4xrqTedzehlRjqmOBI8U0sUo8Vt8Dk1BK0Xdd413IsgVWvnXfmObnNsX2UXBxlKyhjpQGKIQE71fQwfCHfzvsV9pYtH6JekKCFzMUvcXNWnerbuGE3SCfDa9mqw577d7/Archq/ZZ8Skm8V43k/rq7Da2jFJT4WmnJumFflacYncXqelWjFz37m8ViiFU7qEaRz35NyFFoqkKGXO6sbm5calkWj1K5EVNXZ/ulsmmizY0hFplEELlS9HhgEB7n +kdzlawQu+mKMEZKlVeaRMUNDbiXmI3jnOF/dF0+JHV4a/l6OK6DZwgqVcaQQLlLkpEUogVqAhCBZH1iriA3OjrlgQxDy8x+pDU9SxvnJoV5sWqMWFAVAyh0UUVEWAr5rUWRcXcEk+2JzAwMdkdwghWzacULFDN9QTaQpcUHsk4wVIkne6KsVHfZnJxmYJFHrl2SL/qmPRnB7I3CorrQ9ExL6TukDgDI2Yak3js7IcXjvyS68VekVUMXz3kx5jdMV -c0X2hkMQUvICh7l2zw/tK7I6URao1y0SAfJAlviZhDOez+UF5o4nUXlsWnsXoEWHFxL0W2sWBmkz94onlY8XGfkMUWfjnmXgilCXCwuNmpAFxvq+sVCsU8UVe5Tk8WQCEtwW8CgNGGiyFEmp80Y4lqAtFw/navSD8UN1Fwu6pp5yRlqsX5gX53kw7mQLIHNmtHBxYQcvgd6h5+L2mBqJzznA+pAqfgEnkpZgDfDldlF8XR0USEWdyqgMUmmwxaq+ +7sowvkQVnPkUHsWvkVHsWsSjgZR+bBe4KDcn7kJu7BA2iO8VLoWK0E0Mw2Hzy579nk5GZAXa0/5RgLGOqV8VOcX6jxVvBAlBApAqhqSHGq4KVhD8frU0T9YUrjAV7AbjkqMUx8VyPlSFjx8VBYEonJGXnToW5oVDMX5oU20UUQU9DjvkikoUJDnwBxolTMND6cW3sX27la+jnngOxF1Wkkn7hFZ/Lns+m+B76hEIwnaIh346tWAhlAHciLYAaIhv -xnAdmScVxoXNUUREVcgW/XhzWBPbnYUkCQiipQCsVcUVt8Xn0UqWhacUnWls3QmmH6cYqJ5dnmsIXBGmmWb2cGluYFCnfD5swXrOH3N5uDGPN510VocpQCW2cWWJn6/m90VB8XQzH5cUMOEuAB1vD8q5apJtWDZBBpYQfbxrJqRylOiiWsUx0WKvZl8WMsULwWy1l9TlVNmNUWJ3kOlnaOyBgVJbgrDIZZgjMWXBBKfDYP7vsXkhjs0X9Lksqng5 +RzT6RP3CT3mxlA2sCtMV3MWCEWqoUOjxU8WXfJ5wX6gVeHkfMWs/n0Vkn3DygbTVg8UWNEV54h8Xw36I70Vk4nxUmeqEC7j/+oABHZGpgBHFOKTKbhgXJukTaKDRFbKmTHlFKlMxGtWksSkp65oPZXA5spK3gE1rno8WHGYxICNtzvgRqjjKUC6oCQkibOCIHkkoDopzqgU6Hjr96eEWfoVbsWMsU34oX0Hm0XM/kHEUVsXv8WaLnTb5oFTQcCHV -4+7mV2mt8mWWFpr4oGlDK43Rn1OZhsWFIbNroGNClVaEwGUJH10XYlxRPnIUUx0DdwU8URhoK2FyYwA8ljB5zfvrrARyay9VpLPaksEKmICcUVsXDEVwVbECWakV7w5SOFeMXq0V2Nma0X9gWaHSQ7BrxgSFGAiioMSsCVZ/FDdnLvl0+IH3bVjmzlEvZG6laCbbXIqn1qmPLcwU+IUICVnh4GfTpsXmHkrRpz4aDgrh5xt8yf8hPCgbKzCoKkzw +kY0V1WhW4Xc8VChY8MWQCH0vbh5mMckItFAWJgdkvQUKYYUSSX0GqZkit75Dk/ny/HkKxYFN4/nz/HlZnw5a6gPlLUDlyysRAXaQm+SSTC1uzgtjTYBARRE0RTUWX8UUCVc9RN9wdMWW5YP8WLvlzxGjzqTwX8IWusVg/nBEXzoWbQULwTV2CWrAPzmiQpRHBdhgACXfaKpMRGcW1ZhC/mIBlkBbzN6Ks6RAJjMm7Dae9F4Wx9aECZacvagPo5Kk -BVnHiT6AhcMU1cXC8UjQVIsBH8VHr5VNHZY4hEXdgUiMWq3njkWAQWa6CMrjQvwIhnpqbBoisCWbcH0oXeVGO0XxDyDR6Wd7tSrFZ7gTn/PRZy5uXamcHyj45y63dAP4XB8XeC7v2GoKkUpFozlzfkkdz90WHMAHNlXwCxkQ3CrCgDIdidNI9jLy4ADAAhwVA4wE/n3kUmUUH8V1JhGCU1sViQUMaHkCUIbnn8VAsWX8XaOxyQX7EgMICuhgvODz +rYH50V7yZZKlmZZYMVXhEBiobUDCOByfg7chIMDz3JYOyCOCnyASrm/Kq3kC3MVg0UbEXT0UycXMbIXRpykW17k0gU53aAi6wIl/eyhIVHrxST7RFgmNkMcUReTNAX3cEDHlpJGQpZIlFQRbzkWxHkOjGQU6ZeklMV4a72BZjAXmhnBm48nYcbZPcWOfld86UKEJi79bRgQWuGG79mdg6rCWWJlp/llV7yJzUkoInacpgvOHlni95Fz2zmBJoyi7 -QVroDiggWZLzkWDcVK6BUFnZHgZ9pjcWeS4F2mw0XO3bw0V3IXcVHv7HUHHzqlL/a0hm+B6hpG9pwAEWlfmyCpt3lNxTosU2CDSOrnfZYsXs8i4sXB6JFcDoCYp4L5BAoJLVABIBDgmK96jQPnFnkA3lz0X+EUopBYcRyUSPrHEnY/2kOSmBjmUCVNsX5CUREXhQUcQKTHhPsUH0VZ16N3iE3S9UXKXkgkSDTb5b7eFkClkLpqJayf8XtAV8kWsP +qTi5IQDhmCUPtq89S4kW0CUOsU9HZfDr0MUbcU20W8wUZJDzsKXDG28UkIAE8ST1DAsW9IWgsVhkmX1ktsVOvgT/IqNpW9KwOmPWYcSkzLpw8RQPIAZC+qiZ8APPAbmjJ9yREDv6oIPmsMEUEnnCXzQiXCXaUVhPmPaZh+hJ6lyQWi1kW0UOCWCIVOCUFoVOwXJ1zQvwqKiCwWpJTqUbfCVF4Wd7la+iANTEy7jHlgEbsPkNcVI4qRCVKBxPqlOo -mQrkLLkrNDUjn7ohLdTvOg+NBqVCBaBDwzKUDbnDO/g7JyAMVLCXz0UjQVIHwNcXvGYpPJ9zLYEVuMFq0Wb0Wtqma0XTQWxOAlFilFRkEWsdADLjfJgn0WTMXqcVy+iVdmwaGGxkKEBs3aaBSDzKtzJwzmn1rWiUTzJbIYLxnwCXKUUzNj2iWpPLmq4ZsXH3BVDARdBetJfwoWYXd8ypbJFOyKfji3m9oWiEVC8VE0X7T4ZCXx0XE04qlzV8VPUW +xgf5TaZcPlEXaoGwVcX464CiVgfnRB7ieSyGDHM4W5Qe2wwwT/FCifBmkDcSgG3n6CrnbJk8WT0V38WZgUaoW3CWmKrXAQPCVrvkFoU3PGXTgw0iiTjnbHOm5q0Yt4A0iUGcVoPHACVQuiPsWq2nop6GN6R5n5iF2iXuykMXnxYxLMW3HLeUXMXkDVF/0ZnLlyjkeyECXlplwC3kmjFRK5/gXuXkAcVtJZEkKOSJr26pCUgv5mJCriQXLiSVQMPS -EEUIwXidjiRjTsJRjlJXmlSyGoghTqt8X0iVb5aYMWq2lqkxpHYSl5AgGGqxLRHIRYwrHQvkYrTaPZYwquflnAVXj6VflEgaa/LY76+PlpT6HCmfCWOuKqWrxukEaK4Bn9Ilk9l3szxUVSsF7HHv86Ff4pAUVLEgEVkvqw9Dc3ne0X24CGMTRqaDbYhxBifAU3I/ayPyBFnmxlDSVl6CXF8UGCWi5C/MXS+oBHamGk5CW0UV5CWTQUREWawXhJk0 +s8yKsjDyGa8x38i7qT7Hm5sXR8UU8XUAULcVQHq02FToXEkWBQVusXNIUjMXzwXmxGrgl5VaGNm2XlQNjKvau0UGrla+hM7A0oXGql5Yof3kOckPJk7QYkvnhr4fmbuUWBuqSiHg8mWzJs6FlcUvPk7kULAV5CBqAg0Pq7UBxxBMXiGnqd8xg9zM4JVsHVy7piWUMUU8V89BWCUrMaJ8UuVDhYUj8WfMUcsXaOzYIV0dBiOQ2G77jF77SQ2RHsSO -WboSYLIXO7G9wjEzQRMXo3mZpzMXL3CVBU4n1q0SnSsnDJGkAUdDGYBkrOEm8FIpZGV662lDEFNAWCYItinbuzVIUvw7BtG477QBFdiXdjExNqUib4/7195EDYbV7QSVdqIGKlXAWbHFR85WemvIUSZa7oxdrKBxF4Z4tHkTQZGYZzi4F/lKUVciUWBFrUVbeAHNksUKiVwDKSr6RhqTedwNDRcvjH+ItTi6BkrcEikCC8W1w5E0UuYYMsXGCV6x +8WrdgjlrEwV1Kn8SnnLzo5JoWommEhgLAHkMNbYuIpDqT6zS8VFnJFDbVt4HL67CF3HY9m5iDpIGk2kI3RlzEK0EXblAO6oKtaSWKgjasmrazm9JmKYrAng5mz2tDlRjR8AHYKuqjUjbFOyCxkEgUS+zUyiUCXmCULUWIIW+QUXXkKcUMOKm8VHilRcWSBJOZAC1Z20a2jjRhwRpoVXDyARHcXxQiBCWNQHc1quoJ+9F2boLy4/gUt2KwAWnzAAl -GV8WggVWrnpIVjkUREUpwUDgURmGY3ldxmp+qaJgb9l0iWYAVawQu+lX0XeulVeYX5atoqAoUoqFC7ngj4hR5S7nz74B0zlHbavRaSVK/lGMXPzmdwWtSwZdkox5qAhCBZH1iriA3OjrlgQxDy8x+pDU9T2/n6rncMXoEVAyhbiVcYnwdKUrGEiU7CVU0XScUMUXrwVmAJTfAtbD0JDoXk6LLN9QTaStzkk2S1jGroVyQqdIIybndOkqSk7QYqSW +5u1ErQpyQHLWqRelXqKQkZeKzy8X2hmBfSPnQgYSZ2AMgCgtjUMEMRDI1B+/j3ML96mU/l6sjX8WlCUU8XzcVIIU9MVayyghlsnk5oV1/lbiXkcVJrnJ1wMQh5HF+/nxG7iRAL8WACWoIkWiXlXkvwHxbKssmd2EWQXbCHHYFnrkVeJsGrCXkeGFuSVplGRiWbKZMSDkj4jjAvaxJDHiqBayEnlTBiAUjC7qRbIVrEWzcVT0WcJhx8XbsWhKn6xF -gqHf3mrdZ2Xl4+BvzlnrJjIAHchsLJoCzsk4nGAbfSk3js7IcXjvyQoEUpCVsSW5vk2sUkCVKD7BnKDsKU0V0UXU0WNeCsSjgZR+bBe4KDcn7kJu7BA2ihSWPbCMiX8UUZ54dQ50LJ6QUHxzOoWZrasNggryboXGOpRgJuoWd86HkWFPxVvBAlBApAqhqSHGq4KVhD8frU0TykW5JxIHzJCXI8UlSUfehlSWcSXd4EonLoPlZ4W5CVUCUJVm7fQJ +ZUUFgV1Em5UVbwz0IUIozzNRQvkygxhdYmGpJtyO8XxHaK0F+hqwgwnKpDxkX6H0Mx+hqlSUhgWubmf5YW5GlMVd0Vez7SUBKmw4fS2FzN6hPhhvOhKEh5BAZrizgVvyAmrAlCWG0VScXG0VT4V5Olnup5bFnZmEiXSEVfMXaOzgbnNcQ1ng3jnsuqVQFyZQeMBakU/CXF4Va+gb3g61GcKbhdHudDrcqUvZCoHjiQNzb6zS2WmVsBblwIwk3sBT -WTuJxa3mkyK+bJolTMNCGiVXCWLkU2QnKLFXGE6YUY4GQXa2ekNBY4WH6hFCoUx0ClTlCALvTSa+keSQBJJpJjLzItzoSUC9vzpkTopzIkhriX78XQkUOjxrCUr0WstnlLa94HGIWKEW9/na4VZIUqxLTVgwsV60V54h8Xw36IDcXfaI/XhUFkC7j/+oABHZGpgBHFOK4HkufaEJEOcmDRFbKkmXkTlk62khSmhuFNJaN+5spK3gEQ7mESWdAWir +AyWCK38hCkR8gBLpSPsDANCgtjt8Wf3ARmBd8V68XUCU6UUxSV0CWUs5lDjmoHKcXBkWxfm3/najg1lZzoRZ8W2Rm+bKTdCD8iO8XFhgZPkMrKo9GS0We6C5iFILIeaFwQbwyW8yl7MXfqyyyzLTAtunz3humiPix4WCIOx+KCtWBXMX7/lIsDKSW9SW2sVYiUJlrxFzt/Y8AGUQIb5laiXusU20UWbljoANe4IVIUrlj8q55hbll8CU++jfdE+c -YHFIh4XAjQ6iiLlj0WDtsJ0RB/zSaVAe4AkoDopxhwU6Hjr94RiVqkWwyUY8X39bicVjQXK3nEiWHiXaOwzIUIpn3WzQcAa1kvsV1Wg0oXyMWEyVChad8UHBn9nle5roPpCAUEZKj8UTJam1HcQxxalit7ryYETyTYU/Slx+IFN4/nx5XlZnw5a4dwWrVAKvThkXCkXl/ksRDJ1DbKwmiyz6Q0CAwNyUjDART0GziyXJ7mSyVN9xnsWi9CyyVqHE +EyAY2PY6NHIKlw2EMvlzRLtqJ7bzFfnJ7Z9gV0XnxYyVlk2NZiyVJc5MN7QlnLeo4WDTSJjgbtBzUgAl6CBlDjagIWBMUpVsE0sVoiWYuSc3ilEVZiXqSUKh5SOHaMXvMWjSXtkXjSVuGZhQUoXiX0QI7nwr4A1x+rEzMX+CUgmqbRkwhbAhYD9Zf3kxdn8JJ1bnu4Xq/JmXbvGJCCkbTE1GFvgUmN4/DbLDkfAwOIxahmujEcoUVyFnvn87kRYp -xiWjzp3UXuSUPUUrwVeSWEEX83Ec87V2CWrCMrmiQpRHBdhh4yWvmJ3SXUXIigVPcLpxYJPx4DYfSV7y6lZZjMm28WwSVbeEy2GgcacvagPo5KkrYEBcV7yZZKlmZb/cWLiTdrnXZCrsWr8oC+4c5C8IAG+QJdCqmypJhJrBTsrjKjCPm78UnsVQyUXUUJIVKVnShEXRpmCVqiW/oWzEWL5kc8xTbBBdaPLlqrRQUl5HHtSVzeT42m2iXbGpi85I +D8adg7wPr5QXrLm/LrzfLTCp1fzryagQLiCWy/mD/lOoUG16+DHV+4Bnlsmkq+HFyXQlrpIUgv7jITZBCZkQYELD/qx8CgBDeOKGoTsGRIfmw3qJaI6yVUCU0UW/rnYiXkyWiDQ8Q5jylk3mqPnlAyEZCfYLpAhVSTK37AbQhPDci6OyUWiW/4opk6go5sZYsGI+vlqxbFDIQ8bSQK8C5ZUpxOEgUbKpa5xYy47vLwPeYvZZn7kpUa7qI9JbV5bA -lFQRZ/sXEXkOjHWwURU6KuGxnDDsUFFqUp51Np4t4/iUGAVd86UKEEHkLZDgz5BOlTDmdg7fyVwCV5gUjHllmSIZkHNnyJzUkoInacpgvOHlni95Fz2zmBJoyi7qTi5IQDhc9TRyWuMVtMXVsVwyVxJYzFZxiX+gX74WJoUZJDzsKXDG6iXEJnbHCT1BP8Wn0Uv8VtllBBwJDL5b4T/IqNpW9KwOmPWYcSnRPlh5HEQBM8VMlhRhLwCYAZC+qiZ8 +UYjFzbWbwllZfzBOm8iUjFxZf5Znz1lkXyXqmEtvm7/5uG5SCUzk4PyXqCGp7bSyUqa6orzbyUx3jcW5hKzT36yl6cQW1SVlV6rAS8RLIBAueC41BKjh3WgoIBTTDEK4U/lc67M9lDsToiV6yVcZgZAVG8XqSDJXneix9yUmnmOFl24z4IBEYxv5CT6g0cWU4WgxKvUApcVkgi+FkmLmAgxpHYfgpocZ4CksaKwHmY4Vd/zhiB2qm6CTwDKDgCkz -APPAbmjJ9yREDv6qnvmsMEUEkIKXzQgPtp0sVKLhwIk35Avk6uNGHLqVoFIyWtcVa4XKEWToXJ1zQvwqKgfUWpJTqUYkKVGiVkKWeqGekmhIn3iVboWdIJgf6McmCKkQ2J1yWy+Ge9FN3ncxajT6H1HvPoS5aI9l5pJ1iWGeL7gVpKqxwUfQWv9hNN7rsQVDxgtYwwT/FCifBmkDcSjEvn6CrnbIsSUqkUx0Wi5FxyWiDTXASYKW9gUtsUAYVJbg +yIOxk4b4eKeaAkfLAEXd8UWCXLiWvSXqiWbgHpvm2CVwvmrcUFiWOCWGoWuGCEpBy0IUqzHbDJfmmTFswksFBEGQUKW7QgCCVWGLaVJI8W2MU3gUOHwnZLF8VF4F0mrafnJEUiSVkPQpJx/RBsSwdlnXXDGJDDzywADZEDZkl10lpTREyU2sU4kV44IhcWBGZSvmjykbiW6SVv8XuzlNzhp17wglt/mQBbReIj2BWJgaKUbBYwRkLGoAhoXmmtAV -w0iiTjr3kvuoBxhe66zYTXiUaQWpnCAUFDUUsUbbaYboVOHGazFoQX73l/0ayL48+nd4YnhF+Pl3O52dk4QU3q5plyg/kmjFRK5nCm1yUAHY0G5F2mOSJr25dyWkPQ/5nEQCpSVnoVBACC/yzYDZXR54B3bSQIQiKia8x38i7qR+XnrSXhiU8MUiQXqoXXUV0tFnXiS8V+xkeSU1SVpyV1SUMYXmxGrgl5VaUoVwlJQNjKvZqcXaKVa+hM7Bm4XG +nzocxEyK6tnafsrjCXkjHrylA2xP7ml0UgzH45G99lMt7cTaNjFjT5ixY1Katv6cfn/pHZ0WB7FLIEVKXJoFwOLX1HPZI/P58iXrrkix4l4FHxZFIYjMFinY/cXBxEs/w62nnLnS55GzFAIXeZATKgCIAeSR5fIo1DPWhRgCiUA3WiIOjt2AYSUXCWoKVqMUJbnZwWqnRdWoCYl2CUEiVrcWFiVRYVtxDkFxjh7oYgS5gJcWhT4SXioDIUKV/cl4 -ql5YpTvnUyU8IXP34PZaZMySiEXIWuHH6emwe51KU8ho1iV3N5pdkx6HOKVB8VNIU3Ci3lSGw6CGSvRxXgBFMzYbAccr2CgDbbw8U46BthkhKW1cUi8WGCXbSXrCU/qExwUKyVS8VsgUy8UkiXaOx+YV0dBiOQ2G77jF77SQ2RHsTtSWrdgjlrQ0YlHnu3lqAXo5JoWommEhgKdn5Elj2wUR2H/pGwUr81o/B5TUWR1gePkaXkZ5kmelIGk2kJCC +KEIczwx5nKXblx4HZI4VBrqjZn3IpfnzoBICE7udxixF3cVzpZnXrzDmGYFjYIgPoYcZdnpzL5omoXkY4PoYca3fYYBnh0rHjxJLxEGowrzQ/KkYVROl7pnjTBRMrBkLOeq+NCVRhrojW4CJhLNACf67JxgzcW38UBYUuYaeKX4VF8zx8IVrKXSKVEiWyKUd7zAYXu3I0TbADCzrmMtBxiwDBg+CWvmJ70Vy+jubCEDGh/l3xLQyUuSVdQXNJnAL -Wsq4G8XblAO6oKtaSWKgjasmovJlgroGTmGSUvXkCZLAng5mz2tDlRjR8AHYKuqjUjbFOyCxlfAWmbnCKWYuSc3hiKUuYUFPl6zZZCWz97XsXKJlOLk5SxOZAC1Z20YLtmFCb7kIhnDgDB1vnAUWQYXiljyuQZXlt8YTdGhzlZAp6KnlkUAvmfAwAl5u1ErQpyQHLWqRelXqKQkZeKwGYWJ8UP0hBfJGSWjXiPnQgYSZ2AMgCgtjUMEMRDI1B+/j +LqekcnxHp7h0x3zb/Gyt0V3AomYVrOn/cUYryGNDOb6oaRXxGSqUBHERgXnoVlV76oQfgTL+gN4HmJDBdCZEbHIga+CtWJPrLIkiYqXg0VBcXJZxwIn4cW4iVBLqGUUIvlW0XEiVkuA0wx/Go5Hh3ZmaQWq/TE0gUMQUKVc9TcdmJCW6EVgxrMmm7YGRlaVC6kvn9HEMEVmKVLzmYkZn8EK4xEADsGwn1STsoHchbez/RC60UL4QutyuKWRSU7IX -3ML96nUgV6sjHsWfMUK0WefxRiU34rp1GIqXLKUpyVScX8SXaOzXbnJ1wMQh7yUTTl9UmiOKPBR6yVdNlNEAWGJY3lfBYUyUUAU4E5wSV1fp+xEPJlsGqv3keGHtqXR8WJSVcVqLYU2vTVKk+yVnrJDjLIBAjjAvaxJDHiqBayEnlTBiAUjC7qTy4WR0WCcVnsVbSXtMXlSVMgWV8VvkVTEW6kXHimp0VUWlJIT1Zj/cDz/7cRkwfYmGpJtztSXx +XCUriXhZbeKUBV7EyYRcVESXm8Wn0JGCQAGRmGDsjnULnxWFGZjMuA3sUWSUMqWL/7ofoAiWoNrumq+lkE9lfQ7RsGnRn3gGUhJCYIfAXy2rMTnMKVXjzLXZOrzuELh6IrgK+cQtpLIOzELBBmqoSUYQVMwXIKW6yXbVKz94c9mLKXWwVzNq2wXykV17lxfmOrDk3Bv0FgYV5qXHs6ANQ7Xjc8U+ElV95hiUws7dAHGy5jA6ZNKd9HWqI1vnJ5Yc -HaK0F+hqwgwnKpDxkX6H0Mx+ho3qWtwWKFGf5YW5FX+kcyVnMULN7BCVYzk3CjSUBKmw4fS2FzN6hPhhvOhKEh5BAZrjgIVvyAmrDTyWpqXAMWgjnyiXdBCegVrqW0KnJ0WbqVhyIGJ4hDJn/AijizoW0Dmv6A9sW7AVSSXrcG5iWP7HnFY4cUX9EHyqF5lCoHjiQNzb6zS2WmVsBblx7kXP+Be0Wa+S9AA0RT7UBZCxZ0FLpSPsDANCgtgrSUrj +N4SllJ+wfLJkJDYyjnUDlUDQwRt7QhlBmIhfOgYqURSVYqWlEULKXZiVGeTqNx7sXPdkvkVBEUkqWTcz2Dow0hrPpqxlzsKehhP/kMcVke7O8UfNne0V4aITeKdB6LOH7SUVrIYszf0XFzowWqQSXmtmbqAPaS8lzvNBADjplb9rra+IMDSKfY/8idSX/EGqrgLiXk8VpoWnm4YKUjeHdV6ESXKJmkLk5SxkjCaTJGsiYrBPHlcUX/TFlqpHcWq0 -ARmD2SXFSUnYUu24RKWPZ5lDjmoGqiVOsUoyXKEU1YXkRgPgzYxgmVaTdCD8jtSXFhj2fkMrKo9FwcbquEw0WIvmynmXlAeaHQfnWEWBCVz2oGgW8iU3CiyyzLTAtunz3humiPix4WCIOx+KCtWBb8UPgVIsApqXzqXoEVjS4SKVh+hLQEeAaflkVlnVSUHiXUCXf9CUW44zh51layULtS55hUVmVqXATkw1iekEhanLHIo5YXTzagVFwWYLHlUH +YQsW+wWxKWt9ZsWkR44jGkyyV0HH9MFzAKeUWcC73SlBckwCUAaIDAWvPqr+mzJGzCVsIq3gUmQ4u4VtsUMwEhwX6KUJPy97Gsq6fDZe9HY7n6emGk5Hyni8XHy5pFloR7pxn2iFVumSQF8AqsrZtIJeSXt1GiIDO4BzPrkgDw1zSx5t5GEag3yRPrICKV68VjqWJVRpUVvSVWImb6K0aU5UX0aVbwzYIAV6bbKg7IIViVkyIuhg7eQUKUA3D0SX -OcHsSlC9ZpAXJ7bPwXNSnxYzPlk2NapaX55awEa/lkfKUeCWI9BKlnlllylkxvm+QQ4WDTSJjgbtBzUgAl6CBlDjagIWBMUpVsH4CWqqVSyUzKVx0UCjE6qXKgXRKV74ViMXk4XSyAoXiX0ThHnwr4A1x+rFZiU4aUgmqbRkwhbAhYD9YzvnxgX8JJ98VCUWvCXNVI+UzuLw0CkPKVVEVy/mF/7g8mqhYOIxahmujGN4UVyEts6qSm5LFky7IzkI +imZNiU3YV4WqF2kPNqSxYUTxLqaaaW/nmeAV2MW3C5LtakYri/kaFmF9oFKwAYTwwS8dyMAAR/xU0SU9D5yTfLID6iuWRKiXL4QVIVvqWGyWdhmkB6+KVu/mj8VzoVbBBIBC+MFke4d4BWlnOm658QRbApcVMAJC4U4mGbPkTRK//nhCWEoa9VEl+puWmWIIopZCW6fKVGOIWPllJal4GNZErrHzyWBiUhtFrd6+nzJRHCgFYwqDKbOPaWd4fS4e -QWWIFcuI3yY6a4TAJ2yVLEIzdlBxGguk2BpLjmc7mdiGpF4liXEwUq+F/yVT8UjHlFYxAKVd7nz3ghdD5WbD/qx8CgBDeOKGoTsGT//mw3qJaJNaVIKVWsUSPlAESSKX/lw8Q7J1l0ZlqFk/PKEZCfYLpAhVSTK37AbQhPDci4jaUgUWnBQNmYRSWiW4JSUnZYdDEYQalvzyCHiK53gHYiK+nx8HLKpa5xYy47vLwPeYvZZjHF3/nzsnqX7HAZcH +iVhHqCXnNE77aWxKx/XkX8x5u6Za7jQqoryyiHTc53j7tjFLqkxAoM2b2gouTGxKzf1nqCX8VTCABk9RhiBxkReboemDOrLK0rtLywIRHehKUE6qVZVFXs6+aWiKWTswFAXGnkxfklOnzqUoEWA86wUhyuTWnkyrABtY7tLmSW+CV3AnACWkkhbYXoZLZowl8W4Yr+gH75FSxF7SXc0W2rIoo5n2misUKQTnBlOt61Wm+gWhiUSXkU36Sslma5p5 -6HnRZaUho7FoX12KR8xZf5ZnzuaXFaXqmHp/m7/4EAUKmBkx4mnmZNJi9bh+H6YIM6Ux3jcW5hKzT36yl7eIXZcU2EVFYypnnihATHnvJA5cCZkTDTKqoQQlDOwqzXhXwgdTiIOiWzlQ6WiKVcZjdQXOSUQpn+a7/FK5tEiaVk7klOl9/n4IBEYxv5CT6iE8Ui8WgxKvUChSVkggPSVdSXhfI4Nm6wKeIUCxZq6XOiVESWAgxVQzP/nZRhsRC2Wi +k/YWNwUgkUHyY18VLkpMSCYdgdlpy4zZbL+pCL0T0gAdBaPNEjE5uEUqMXeaXk1B7ZldyWPrFh+oeAbFMlw0XQpmp8Vs/mmP5pSUnNEXEXVVxgBIwhjDaV6IJlE4tZE2DTdzKGlnIlkjI4x/nnyi3yVlLGXaVnjxW6XZAaPqJK5ntnZ/9mjqzO6UMyyDgU/aVHsBEfZpnQARTiqACoICnRxIQSqBy4wpwVt6DVqmxqVOYoU8WFsXfoV3CXlLZ7EU -6CTwDKDgCkzyIOxk4b4eKeaAkfLVcUbSVnsUoKX9kWXfIxwWjQVIqXjQXsgV7CWEpBy0IUqzHbAhAWmTFswksFBEGR+6W7QiGyWCyGjxlPilCKbkIUOHwnZI2HyIZkrpYomo5mn/yWDCVTkoeoU/aWjXgpJx/RBsSwQVnXXDGJDDzywADZEDZkl10lpTT2aX6CWmUU8jEZqV3KYX/JV8WeaVHSV8NlNzhp17wgnDgWQBbReIj2BWJh16UbBYtvnz +v8VmyVmqV/qVW+mUZqkN4dRhF9FZFRse646X0qV3sUToAngZE6Ve7HDnnlyHlrLSoF+wXJHpsTb0E7XOGftZDfo3LIXJ7IaVZFnIyWltYbVyEIyo9glRigkiINxeiYYbBPNCR4XqoCoIQR6VFW5XCWJaJUaVGe6BV5vMXyDmkcWHsWa6WPXnXan/qD7vmbbm6Fom5iNODDaWLITfXlRHQKwWh3mqfnGjG9iX5fl+XZEVwpi5Xj5WNYOTGH6VNYW6 -KpZHk49lEwXXN5ProbpKtnbnAW96zAzEjiGzJHPyXFTH8rGpIHVDlMt7cTaNjFjT7cfkfwbDXYq24qeli+GiAVLIGB7FtyXAGWFKGQS64Ra2KXpxnH96IAHVBYg3Z33nbrFbk5G8Us/wMyVtil1KlGzHN9mirahqU+greZATKgCIAeSR5fIIEXCUzPAY4UpUgVc65DIWW6XqqXW6UKwUy3lwkXb4xdWowXn7SU/hmXLlVzlssVCdjkFxjh7oYgS5 +sW0r6gkjEgzksxLACb2bP9ADax22z+4BjAwD6hfYD1aUBbJT0XoKWTqXwn7pkLVCUEoW71l4Val0iUcW/y4hKVvdIacwvXzZ+jc8V/cBEOgzlEMH5DNk5ul5+HxsVXjwyYylOpcfDOkAmhz/axp2BY4KiIDnGr4gX7mgnU7P6Vy6U0sXD6UnK4ujw0yVFiWduCZnSefCVog28XkGY07EXm42yUMcUsHCPIXUKUKkbXux06UhoUGdnkkpEIzIpxKs -hM/lYQESXioDJ+6V/cmGPkWXnwDRCGXIQp4Hay+KnfbbnIEHbjZkH+byowDFw4BHC+FzpZnXpTjmGYGnaUV0WzgV4im/CXX9EFOoSEITkpIaKutnYg7HjxJLxEGowrzQ/I1EVROkjHkJfKdcylMU8USGVC16AiTxmDm+NCVRhrojW4CJhLNACf67JxiQyVfMXQqWzKU0GXzKWk0nBEVbCVnblF6UoqUqyU2rC1I7b8zjICMCUTZhxiwDBgFyWqBJ +ghxBpEAIDLyXQAzIa6gtsnerKj5FQ6XZdDCNqNkXH3gccbEGWbKWsZCd7zwTzpODqDkrqUmyrD2ABtTDaUhnDxaVADaDPnzNAxFk2LEuDFmp6jGkg8bM0WcJnN5FwGVQ1KLZxgpKMgBqCoWzBqfhiVT22rHAA64gbMSXkVtMWR6UPMXSQXYDlS9JmYpSGXDMWkGVhkUo3R+XBuQk/8VpZZAHB9daqGWITrlqURJxRraAlEDPms7keG4N8YEwUCgU -FyXubCEDEnwUDrEqaWtqUKenNjby+Hi7kTJZHp7h0z39mfAy18ZGHa8TZ9iXXjGWHaGNDOb6oaRXxEVGUBHEuwU6aUuiWW0BvQXoTmSnw3aQ0/T2CgjFjmJDBdCZEbHIga+CtWJPrIQyVzqUL6USEVPkXYiXw6UZq5ayzYokAsXS8WJwWy8U1NA0wx/Go5Hh3Zn3xkNxrE0gUMR+6Vc9Tg9kgGV/GmocV6mEqha0NaGMW7GVVylYsVM+AsKXz/Jn +rm5UJFuHRFiSvwU51rL4qLvLVoxHfbsmn02nQkXkkp0czDjI/tJ0gBx1LXPxY1SHXDHM5fNDG5mf3CEx4zKUoKVy6UEdkVCXvGZhcVf6UqcWFwXxZY0YY6f4tpi2UBUqWCo6JpQHiU1iX84Vy+jIMiQaVXY5GcbpqmI/KAQXDO5mvxwAFT9bwBLTGXB9YVyqfvnNrr9HyZdGDDmi85k6Vz9aRoqYUXNYXaH7PxDSqD+aBaEI05DwkiOWhCoCNgDU -8EK4xEADsGwn1STsoHchbez/RDiJlc65Enn9GXriWL6WL0WwqVoKXgqqr6VI6U9/ku6VmIVGCQAGRmGBcTmgKmN/pGZjMuCXCX4yXuECEyVi1F4aWiRFYrQLlkICnT7KmPI/P5mPkvaW4YrKzk2XkvQW31kTqBQ4W4bLaQz3PCbUBvwgELBRQT5RhUiogHzXlpHehhoVDsQiKV89GL6W4DlzKVgMUrVnkukTGXIqVTGWoqWOrDk3Bv0Fa5jqmljW +9RpAWpwWCTkjqXr954GVqSW4SVpvkFn7EcXfqUp8W/qUdkWcgYFXacuQwrKcAXcFDjGSLSW0iWboUDGXpybMQUmq7jP49OKTGWxK497IKrFjKKDw5+oE8Ple6VZXJRQRiTx3sCWACgtgVDDKgDmjxseraQwD6ik9htyVzf6iGWpUU3CXU8WOoDYfmk3m4KVXznBmg6JD3Ml0aiPrHuFme8w0+gWjbDaX4lSfHlLEJ5f5EXwyBk/nxm9mwnmbyZx+ -AMYSgmWFyVTMXEGHdcVVCWxhatKWE3ngGXmnnDNF4xwU9n85yHeEYGVelwJbnGgVJ+wfLJkJDYyjnUDlUDQwRt7QhlBmIhfOgeGWPGWzyVUGWtaWaYzqNyBGUPvlKyUTQXUCWTcz2Dow0hrPpqxlzsKehggQWSSX46Vke6HJlGEU6cV4aITeKdB6LOEUaUVrIYswWcHbnIwWrCqV4QacFlpsV9yV39APaS8lzvNBADjplb9rra+IMDSKfY/8ggaX +KJungl5zR76YLdqJm+bKPo0LR+jY0LT/jE9KWsmJ0y7rMV42BfRbUvn4LIUpE/jkk3JioBG4iHM6mznOxg2k73hg4TRsUJ6I6F/mhpA2UBUbmYSV3ViqSVbEWBWEmbHzxHJ8UT6Ua6X0VkK4wI7bLNZBHlO7G2XnW4g+IhFqV46VACX/GUQKndHkWvznLxVTl7nLpi7W5HKpGInHskXRGWtB6KuFFM4azHMxEeWkoK5AyGk7k1pwZyXXybF8xw3n -/EGqrhTKWsSUtaXL6Utc7Sxx6qXNdl9MU5SxkjCaTJGsiYrCJXlQsX/TFlqrpKVOIURFQJCQRaVNwXkBZ/pZNSnZaU8HGYdkNIrl05CbmZXrcllRRaZa4nQUo2GIsGP6UAFZ1ooUIUmQ6QUU1CW0zA/nz3NbWqYVt6qa59DlYkrJHmraU/VHQtEaSWWyXw2FXN5utmB8XEKGSQF8AqsrZtIIdKV09nF/kMKz9qVuKV39A5K7O4BzPrkgDw1zSx5t +YCV5UZvOxTcz2ChIIDLLo2mG5ZAqUCMcKxFCYmVR8WaUW1GU3GVFsVQmG6gUjEC23n9yUxPmKEgoVF+pY9rBz6V9FkmmJA2R3Tl0GURsjniVVcYNxI3fyMmqKAE0mrlHaGeCRQZQ6C5WLVCERSop4IohzH+KH2SmtCzIT+cWy6WiGUuYb4mVbNxdtZfqUusXrKUyKUvGWKvk/ezYBCtHTKHnFKbRhhv/lHcUdZlaKWmPl8gXNSmQykiaVRK5Ylo+ -5GEag3yRPrKZ6VC8XbVJpCWANmvGXVfKb6IZmV8LnvdlozLYIAV6bbKiZ9nYDGPSQuhg7eR+6UA3AlyWlWmK4oK4p4WoN0W4E6SxYUTxLqYJPxDaksGIFCE5cp43mkYrrLGMeBCoXP+BQiUnd53sBe5ZEfIfJA+ICmP4RxB8SxYdgksmZU6hiWlUXXmUBEWpmVbSSh+Z7iXCMUb6Wu6Up3kjxZ9/LxlC/dm12GUBq58QRbChSVMAI/fkxdZYHZck +UzlbrtgGSXkJmW8MbsvirqTjFhOsLwwQq4g6Bzs1FyAh0YTO8H9oUTmV0sXR6XcYXF46kf6SKWmyULmXEqUvGXI0Xi16vZxujgSFHK3St/rDaXDhaCRmcgUubmKFEqlahAV06nhQ7LAqS+II26zBnvek5GU0SEZlRHOAp1S4MCP8jcoDEgylqHRn6h6XrXg6AVkaXcjq4mWJGIEGVFMhszn5gV23nSGU1NC4CxFoXU1BLBTFUWqKjO5SmiWL8Vu0 -z96KKDblfl+bEoSW7EWvmaNY5bylQtH8EJkJY5f4Pp4xOHM/YFBZViUhtFrd606XK/JJxZYwpQ/ke/TZ8zZWHenzsQHP3nNE7CgFwwppa7awp5u5tmWyxaoryyiHTc53j6a/k7umxKwiukWWUuTFWWXdqW+jrG5lTOJNmXqbkDKjCABk9RhiBxkReboemDOrLK0rtLywIRkmWF8UzyVFW7lUUwqVLqU7SVIaz0GXBOqdaUEEWNeDt2IAGT9phZ1l +UDGUTySr8WI8Wfjmdmo7wVhfZMoWlvwY7LKjSRumAAV5ep8Xl9sX9QpDsV/cVSUXFFGZACOtBWCLs5CnKKugAhtIDFhXsL35p4dh50oiGVR6Ww6UEmV8rA6VwXHllsXMCVkcVHsXXXCiPreWjskq1mUjMhquT8WQ/GVmiVmPEE6UsHC40XB4oc0Uuvo4t6+qX1oUInGv1n1caX+JPIxe7RGkwcOAsHScvoc9BSVLaWWYcUwXqjqWTmWPMVUWVnn5 -v2Zt9znCWLlwlmWM4WgixJhn6KUUwHCJhf8UmPkUezPaqsKo4wUYcWRlYuvo5GVSgXfz7fro0cG1Wk1wVtJZEkL+KaGN6BHFQUXmcWcPKt0VNWVuoULLTpUVq6jSuJnu6K8wYTQmbgJIz2kAPtBCAw+uAbPn7mg9caQqXrQUH8XZiDDGUuaXxyVzxE/VafGVqwUWCU53amP4IoyAESgzlkv6+bJgBIwhisWV6IJlE4tZE2DTdzJFaX65kAF4pgXn +4nieGVj8WNeC+kBXIJ2ojUcXvCXMmCkaxULl0GX/UBDGVPcKPgGvEUr6ZOgVzPmc+qF9pwMCWACAkDbKxcvo/pB1Vi41C/bYw6DoQV03geKXYmUGmUUaW98VqiUGWXBGaKUzvrE6SXtaV6SXmWWGMXjyy1SKCvGKGVBxR1bAt8jDaV2AaMmWdIKsmWM1pmvniRnQ9HHqXF+bnBkQ8xwB4KGlrpRCkR6Qz+jxrogc5C3QZMRBeqjWAAGunvLiRWX6 -yiC6VlLHaWWxKwnWXZAaPqLa5ntnbXDmjqy3WUMyy5aUeyVw0gTqC+yLfwWjXjzAR347wgDw8TbqRerS41BxIQSqBy4yPoVt6DVqnz6VWUBZVEr4WkWXnkqk8qPmW9MUGqVbwylqnOxqkN4dRhF9FZFRse43SVgmVDcVVqUngZWkU0MIECTO34ioHYhLDOG0E5qjFAeZn9n8UHA5bHJ7/9nV0U1GWVQW6aVZfDA8VJNnGgUbVyEIyo9i/0UZlRRD +mV89FRSWl7kiKWdWUfCou87oeqrKVMCXeHksCUBKWQ/nmUUE1JvlKREXjCApOJFdAOWWcWW1iV56XfWi9/n30zchpO/ybGWn6Xzr6QISVhA97ReZCbdLooAynxeXzCcB3SU7ATT3mXGU4mU0UVkVmK6UEcXAuEeAYedlBkWuznI6W3/kRhplJp+bg13ly/CfFyg+z37DDaVLvqAmUhSmhuGY/l6mG2SWIAG/3n5xaAlGICVokJAxZwxq7UIxmVG1 -h1UIYbBPNCEUXqoCoITg2VOYqtMX6mU9vGdZKn8UijkmmXF6XTGWuGB3Hy+MH/qAnES5RmfQyciGsWWLITNPlRHQloXlFz5IEIqbMql5DkV3lEVwpi5Xj5WNYOTFG2W8kU90V1GVw9Bc3kD0WFPygkjEgzksxLACb2bP9ADax22z+4BjAwD6gp4VJmXcjrZdARhwi2W/ioL7nNcVyKU/oWfkV4Val0hSiLTHDF7miHo3Axa6Jovz2mU2qWcjh1Qm +kFtn1KXM/ZrpZOHE6BIYwoeyXJsbcylhUwIaaNcUf3mPqJC2VKW66Q5VOix+FHyVM2Wb7lH7lByU7XJyyWF9pRhJNpK5lSK9zvbzDOZswLsr4a+B7dFd+qrST96XQ6Uorq4qXhOLzGzGWVSKX/oX+KXzqVcsX7Ej/5iBP59kUEF5f7Bsah0qVGdK56UTXAtK4cEG3S5JrFk2lH1Y/0byaXfYVdXmfAye+lrHFc+KBUWQUWSaUK0WXmXkkqrsTm+Q -eBkMH7Wtk5ukzLkvqXqsVijKLfk8UQyYylOpcfDOkAmhz/axp2BY4KiIDnGoXLEL4QnU5jWXEWUgMW26WJNCuSWRWX0UVkuCZnSefCVoghWwR2Wes4Xm79aUx2WX4UToAsHCUKVdSWW6au8XgpYgEVJjDtWUoCyX1gn8RKsghxBpEAIDLyXQAzIa6gtsnerKj5GeGWQ2Vb6QicVDQW297Z7lQMWk4Wu6VwMX3742koyjmAmV827D2ABtSsWUWqWc +JbGz+ToID22rCSj8oBjAxUrz4yWxlBY5lkWWBcWFAXJvmXWWm7GdZI1/m9WV1ZkdaXW0XJWWezmT8WNCC8gjs8WSiYe0pOmU56VL8XEwn25hNQaNQWAkWugW82XRznBtG8XlCLa/F5mLRoqmbc65cV0aoIwnMcyMoZ0RCPtDuNBiUAbUDifAcSg9hHUnmTbkaUXkaUcYWYrn52UyBZSmxD/6/mXj6WmWWT6WWmX1zmUJAVuQ3FQJDn0mwMaDHGIc -fmgsE3yUEfqjVGEfoDW5ebZqYX+CXq6UM2V4+DazxkSWLZxgpKMgBqCoWzBqfhiVT22rHAA64gbMRNMV78WBWV1cXzyVcdmnLlmYq12W1SWbhCPxCo/yJnBuQlYyVpZZAHB9dbH2V0oUn6VSim/8Ww2Ev6WuPk1mWapDPIUQebqSmX7lUJFuHRFiQkAW3cW4D7DxnVoxHfbsmn02m96VF/lPS5tTAfqXsUzI3wbRZyqDU0TDsiuqicSCXhZxkSZw +WXFqUe2XF7AMulhGV8jr8myEYXiAW764qRbPwX0hp8boLHK55EdUUlWWqJ7m7pJEDpACy4zZSRkyCCGSSZTJ/zIICAKnE84J/rVGW6yVUMWfMKJqUniEJWWg/kAWXjSWDITwD7ifzE2WdICPwL7CQxkApcW8lR5WVScaskW9vTDP6XtGRQ7mhKoGlJ1RFBItjr+mD92IHUBuQLZOxLgh5HmxlBSPkL2XKiXYqUvSV98WxSVsJ48agtkV/mVEqVjS -LerIftkUmVqqUV2VXdnQaUr4AHXyVNnbCW5qUX8XS2WhzZt3JEgQAmUuUWOaH2VxMdQhaXSLmFijDHpdSWZKkRcXw/J8IW5br1YL+R5T9bwBK6OXB9YVyrZBYUWE5UyZdE9jlOoXO0UqkaRoonMWciWcyUIqFtTD2WmeiWLsSBSz+mqIAD+aDDnmOWhCoCNgDU9SdQVPoVh3kwXp8OVe2XpqVV2WDNY8AHuNEB2UVYVtcXxZacgYFXacuQwrJKQX +XbiV8gAeL4UGWAGUA2DCqEOHk0SX+jnN8By3HRKWVmKFGaMxFBjYeiQP2Wv2V9n6ijLlSVCmpFnKeMUjHnT/kxCVU7oNQWWBFtA5ryW2nFAWL3e7Wqa0E5EXz5FHI8XVb4JIVjxl++lFaXQ/AHAA+kAYELooBV3yOsLd7zbiQ3iHUnll+I6qVlCXivnv6U5QELq5NGXfSV42VkQVdADX4Z1ZS+oBaWHmMX0mLc8UCMTqGUC6I28k4Z4tKnROUuWn -cFDjGSoMWCsX0iXXeTsWWBqFSfbbGU5WVyebaOWfS497IKrFjKKDw5+oFM355aUNC72OU9AU8UTwtpiTx3sCWACgtgVDDKgDmjxseraQwD6ik9gUGXEWXYUCr4XL0V9CH39aLAXI6UFFl24w6JD3Ml0aiPrFlFme8w0+gWjasWX4lT2qUIWJ5f5EXwyBk/nzUfo8KyuyU8KyJungl5zR76YLdqJm+bKPo0LR+jY0LT/jEOFkVix0y7D8WJzJA/lA +NXkxEEpF7ZGVccW4Cr3gBfGFkjB/JAMSBxYSt4A+uBcGKJoUL4TOWrP6UQOWfmXSkUkEHYgnOsVpXlMUU3/n+OUuCWtTTb/COVBnnkVgXVSIzWo1uQYOU1FSYznGuazXl32V6fIY2LgPSjxkU6iyAUwaXebkEPTU8lzZwc9BzZzOtABeDFjT7PK3GBFrj5Yn7mi0Cr96VlCW0UWeOXsiol85JBmJWWdaUWqXwwVJbj37A4kjMdlbNos0w2biYKgY -rmlKL9CXGHnT8UjYjkdmfWXIOzG4jAngrSyaCr5JH+4AUwxPsAKqDNOWxIX+OXr94V2U26W0mV/y5Ci7gOVrKWQOWARkv15FQCl3SnCVWMDW4g+Ig8mXxGV8mW1AyaryQJ44Gry24L/lfSbVjbjOJcyaq2Ec0WtB5yL6kt508G+GEcqUED4NnxtA5IqHIcZXaXXybF8xjPmp2WXOVBfJCkW7mWF57x1AgZi5/QG+Ri/xXGC5ZAqUCMcKxFDNOVFS +OU9Ymr6XRnR9AWbab0HHDCUq25x7GlQVKBzpmHyun7qU3HaTXkFKWUpl5KXU7laaVgjaO36ts5+J5rHpABGeqbbrGpmnbeGO460NZfDbCMXgrkSADXyAMARFngtDTgYSrlrzOBQxCTKg4EgI2Vq4xQTnI2UYiWU4UypQaMVR7xqz5zmWVOUM8XVOWtGXPCV9uAVY6KIBLRkeU4hwSIGrZ6Xu2WN2U39p0skZLn1zbzTaTenAkrmcYcxYyJ6f7bmm -XI8X8OWbiW/OW70LYq67cwAuX5qUoVF+pY9rAK2VV6VbKDl2TO9yY2W8mXGiVd2URsiEqVVcYNxI3fyMmqKAE0mo6SUgXbRPm8C4+9YablQ6C5WLVCERSop4IohzH+KH2SmtCzISEWUpCXfOWLqWoKVbNxdtZGmUL9lMmV8SXAsWiZLHmSiyBmnhPMlt5ojWBxGUGnJFyUdZkN6VADaMoVJc6Qyn1mUYwrsxYXOzlbrtgEj2F0cVVkWpUXBFnBmV +l9HmPVA/MHDxkxbIzCX2wEuzatZrTfZxCW0p6ywrt4Ux2XB7LBSz9dqtswa0rsGxUrS5lTuTJYCyUyDopymjlRWXtyVpoVu1n1GUDLHhBYJSV0WVeGVbKWkiVqEhjVRUeHrmVV8lIXGmmhHcUlcKdCU2THe7kfyUaelnBabpbsiWNFgD+lXrlHwqNYy9UXQqUk3JAUIgxAKaIcJpYyVo/KzwTuTrvhgupxBfk9SVuKWqoWVIUr2UMmY8AFINkDMW -OqjsvirqTjFhOsLwwQq4g6Bzs1FyAh0YTO8EiEVEWWBOVOSV8uVS9Kkf6XfmF6WS2UhGVmmWZRkh/avZxujgSFHK3St/qsWXDhaCRkmwXH7kPqUU+4d6UUOXLArSTkvekKEC+7J6SXKbnBFlHGUv0UhVqc2XFDDrohvpDPOxzZxNszcpjRn4g2XrXieQUe2XL4TY4XUGVkYVK+62qGMmXBGXMmWhGWycWa0RhQD5bBSMXadyCo7+hE1rCsWUTyQO +J6Wl2XmqXJWW6iX7EhDujZOh9kWk8H1NRddR9GXqEVy+gC3AF6WVmIbGVfAUJW5AuVbLB8tYGSQmmHHvli7kcMIQLFD763wV5yyeuXymWyOaZ9ztvrfkIIDLsShHUC0RBoID3DrMIUEgWuFJuOUdMUD6DTmVUKly9ASEX7EUPWVmWWa6UliWASSinI5HhW7ks0z/cDn5AJ9JWuWCRAFuU8aWXUWrjqg0rFDmr8F4E60xkry5zz6rqJgl7SKkJ/k1 -xElcYnaX6Bb92UUSSiLZqxZ4RL1OIz+F1qwtCXLjZoCGyKwdCWlHm9uUy7nbdmW2WDuUWHmZACOtBWCLs5CnKKugAhtIDFhXsL35p4dh50qL2WBOWlSUhWVwqUtsGgik4EUHSX7iVUWU/GUdcVJiVo2nskpPFmg+JSSD8WRJOXP8UpOUsHCfsWogVbGW9C5yipduVYuXd8XXrYbmUu3mFVYUeUlaV9aiX+JPIxe7RGkwcOAsHScvoc9BSVLgeUA3 +953O51tmXblRsERHr3OUO3jhMV/nmTtlZQWBuk8+5Fb5XSbdGFyRkpOVrI5KfiZEB/1AD7y3PzI3xbfIRSquCigy5VsHdrnPqW6qWFAV0bnRuVKPlBh4VOVX/mL0Xp4VhyK3OIXJLNGnn+QFGFySECK5rwXhOXCvKvVGU0ULYG8TE2iWMmm1KXVDmYQ6ZKVqOXk0VjTafIJWXZfnl3mkKfksy4HHZ4WwojmN6WDGL/ayXIixqa9dzOazPOgsABvR -mfOVzf6BOXpCXBOUBgD4V4tcWB2WROXB2W48UjzgWVDtRgxEVgzlwlJydi//jHuUVZhDdmPgGuG47qKbfas4UQiVsEUoWWxrBwMCWACAkDbKxcvo/pB1Vi41C/bYw6DqIV03i3NmtOVQeXWuW56UAdkRtBUYVMGViXmPUVYKWduA+yaWaIoXCCvH72UDc51bAt8jHuVFdBTOUUTxzOWM1oi/m/XaZJlrTGI4oQ8wUd5LrJwB4lOXgcZ/5kqNk3Ch +zFDCrjmhpATgB6mWzKUQOUXWXMOV+aWBOoXkqbOVl2WbhC7YCl7IiyDKP4TM5SHCqrDfWVn2V0uUeJxXC4sqVWPFPwWrTFV6U8rGjHI0CkTg7yWUuN5emD31iurz71SoyhjIAHqAcSCi4zXXDE8WW/n2HkYuVzKXgeWuGXBDn1r5meFh5HieVJuWSeUGSXKcxHrCgWUtjlBOFayKrmUYOUHxHl9JE0V3OWSCU3iKEpEymVA5k3A5DCWAq5ts5BxE -rpRCkR6Qz+jxrogc5C3QZMRBeqjWABoDnrXiQ6W8OVfOW8eW3mUweVvGUfCou87oepJyUScViOW7CUSOWOMVVPkE1JvlKM0WGWD37BFdC4eWkKX4eXkBBTgX30zchpO/zWOVm2WR6UyXJVQzfSWjXg8SDt7TX3ApLalCC4ygZJjmi5NtyRkCcaVlJiZvm5eU8eV8aXsLmPabTWUKh4ggVS9mOsXO6XEoV1doRhplJp+bj7qVy/CfFyg+z37CsWVL +SuVlMXGP7m/LDACfNDngwV9Q58D3sCx7KUUg8XinCUy6VPSX/TSnsTDuXT4XFmVdWW0WVlmVZvnv3gquXbRioHDXXb/Dl5dzFASBeVoQ5AqG6sZi0V7ArftbGkXK46i4XYg4bSXzepyxZmPIcnb9eU4XqyqX4sVlV4lawrZydHAfLJioBf8gqS5jAxvRxOqAX8Vt6D2CJLOWDuVNaW3GXzbZnXhjuUJ6X/mVcOVvkVPfjFQq5bDo7A12XuyCBTDD -vquIWLvmWbQb+pmWHVeKg8ItAWaA5+RGunlzaWuUxAxZwxq7UJ1fwdJbFDkrrEwGWl5FjpZKWXTaXjlmd466a7jvlV3mawaPqJ/eVKW66Q5VOix+G7qKTKKGnnS6Ws7E3qJvwXYgWa6Uzk7rlnYznNVjTYC5lSK9zvbzDOZswLsr4a+B7dFd+qlsWQeU8MXS3nLuXf2lmeE3WlLq5CeUROUKKVROW0CU93SbJ5wWhqKWMRRsajeuWSqy+uUtK4cE +kUiOUMzauWV1Ob1Xk0Xli87CeG554khHjJE9KbZ0w0Blv86egXxo4AtHMvn86VeiAPTREoBLFxkABIoBPCidgAHvSAZAhQS7qSr1nZ2X68VeCVGmVSDGaSUEMawNFq6UAVnGUW7eUiIV1ID46zfPDMdmGMYj6hRuQpcUuCpWiWP7He6KIWW4caiAUI8U+MVw8XOMXlyWbKbfpB3yCqUBTXjBHzIMAXULzTBpED10jNyWU/kJXng+WCeX6WV9CGAr -G3S5JrFk2lH1Y/0ZdmWeqX9DG5Yz5FFtcJc+IqsUrMVBcmgDmUuWUMX4sD3mmOOVr8Tbeigkgz+RzWxsAD22rCSj8oBjAxUrw2aWxlCE5nzuWpCVEgQdOXl8Wd/k6qWrOUgWGEoUIaW3sWSBIoBoqDEoXAx5lyHnZ9kP6TGqDQuU+uWwuV4ZhpOVxgVB4V/rrbQXhAqyK5jLkgSVVsqLz6/F5mLRoqmbc67XQwvm9nlFMWItH90XD2WxrDMcyMoZ +5ueV/qX0yWNrBXa5Z6oqKVbKAXgYHtiKeXOmWWSVy+jWW64+UE0FHSXCoFlSXPCbsxG26b+KY9l6feUH1hUyDY1R31hrpQ/0zj+ja6jPGB/Nh6oqg+V5eUZiWauVCeUdWX6UVNdbGensqHoIUcekkGVbKWtIWjZj/MgLWTFUUIQxZqzY+VFUG3nlwsVaiLHNpRRanmVwBIEIIQnkgaINjHuPYeSVzJEaHYhnkIwnjKhpEBZ4B0GxeXzoLDTjmCMw -0RCPtDuNBiUAbUDifAcSg9hFN/l8HnUsXJmXoEWWbl3mUyBZSmxD/7FuU5qXMGV/gXY8X12XoIV0aAETj4sSzoW2qrHGKaKW3SWu+VGTyEIXDrIVEUGQW764qRazsF9n4AXILHK55F0I4JLaqJ7IUUaeXfuWdgpJEDpACy4zZSRkyCCGSSZTJ/zIICAKnE84J/rUyhRyVW6Ui8WfMICaUniF4nhCuXOuUWIUIpmW6gKOWSpFVnbokhxXqhSW8lRO +t8wZElVsG/bmgeXLOU4SWFmUtUrqGTc+UdkW8KgbaqUqX8OWfU476qK+iD1Cu+VAaVX2XCZnc7l72ntAW3MrOjFUbZ7Ibkn57l4hcR/jJ4WC+SyeSylhBCnSIBCA6oKSXlupu5D8eUoKVUMWkgXvqXQ+ULSFaSWw0W1/l9WU22W3/k8dL0YSeHovOBqqY07HQZCpG6i+UN2VcWUToDj+E2uUu8VEAGhHHo/mFyU3eXmEXT9Ydl4l2lsiUnHJFnJG -mXhMG+OmjcHkaUMEWRQ5qeXvuUsEWkLl0aVMlheuC6MT6zCOOr+mD92IHUBuQLZOxLghkzkj3m4flhiXZ+XDEX8aV5+WRKU8aj+skluWNsWmmUJVl8gAeL5N2W76WDWbwr7AXlWqW9sX46VKZh42XoZKFGaMxEzblJRGlkYx8VNzbTmWUaWtZwNILHSEdDEbgVEBbtDFASVsd5EuUlHZ+3xjmWIaEqxbqYVEXwi+WjpYC3Zx2mpvbUMXPqUBCXm2 +tnqa6IUXfAWF2mNZZ6elvEU3HbNgxCH6Y4q/GI/BxR55PS5zMlazGxBnUhnVyGd0WbCV3f5r6SPtx1VgmIgLXi+7ypkDrARP+wDay1Kp8EVXkURuXYqXL2XCeVw6VQwU3WXSvltaUl2X9WVs/kxLS8OiXsTCfbYDEgGQY/A/rDY+WnejnOV/iWQ8WeLIudC8qVLQra2n/DIvaW/aHH6VqebUBWfAHucG9QWg2UuN4FBDtmQglB8BpvaxiGB8GIc5 -XAyEXtlS8AHNl2xgSMKlEhXXDjeVV3yOsLd7zbiQ3iFN/ll+KeGVpqUk/kFuU5QELq7LyWiaXfGVVYVdADX4Z1ZS+oBaWGq8X0mKKOUfLmEYG7vYPin3n6y/lJxmvDZEAEmBWUOWd24SOoFMXmGV96XfaW8BU3CgxAxYUoClxkjB/JAMSBxYSt4A+uBcGL7YV+f4C8V6+VsSW3Nn8eX/CB+2UIjnm+U3sXcEk+2Jl6DU3bCPyzYTa3kjEIzWo1uT +AyACxKBnGWLeUjoUtWX2eV3/CreXp+WnUpEGWwOU7eVHsV2rDgBm04iWgVDy6ZWww9RTyUS+XgE6WMZuIIIlEwLahjbARRSTCHUD4RzuZA7oiy4xRSrjAD4Ry7sEnWUCeUdMUeKVxWUeDaNko9WXD8V+KWHEWoBUYzI5mI4EDbpgHOWfFwi0lyugMcWG0ROXkCxY6cYb6w6EXuJJj3K7ynaEWxmXGXbT7I3KU8+L96JSCmQyWBxGLOJOiq0KWMxH -H+U1FT6mm5BYRvabfYD77gPRN6WX5hPcWgiWbfbX7mMKVpsWaeXwOxzZwc9BzZzOtABeDFjT7PK3GBFrj5YnzXlbzLSBXAMU/MVyBXsioxwVgBXF+UOeWpyXCuXryWXTj37A4kgMWXOUo2biYKjH+U9Ylq2WKAVKj5QRbXIWkXl6XnmKVBeXVhEuDGGHmvKVjA4CfkinYxfbZxnOjG3aEtKlqaXb6ats5+J5rHpABGeqYIGURDSvpaO477GU1WWH +UozxkrK85d6J1iFv3l9TE06U7h5wWW5umEOXX9HAkrppmO9JQqYoWUWUa2aUivZn1QXioOkAvaTKEjw04UoAJFCeNBKGC2Hk46DCpCPSVG+UcYVDuVQOW0MWAr6W2UcOXW2V2BX0Vn0OQPQJFgp8kjFUVKOTCQJL+W0uUr+X7yiz/5l+ULqZqNHU1ocAqzBWQQKxAoJPxg7kTdh3yXB+V/qlvIWmvQltkULRrBVOd4MBWioXyqWtTghtK5Fm3QZ0 -GV4+AjCU3CjXyAMARFngtDTgYSrlrzOBQxCTKg4EgzeXqoC7SqL+WIKXL+UjQUypQr2UOUBm9xw2V1ElZmWI2U4KV9uAVY6KIBRGUg0BRAb2Nw6BV4XmoDJ0slE6VN0VbLBktaE7Z4aL9HxnWmIuU02WI/l43lv7I6SqQpZPyX2wEuzatZrTfbNyW0p6ywqKUWcBW9eVBfIXtIHNnBSz9dqtswa0rsGxUrS5lTuTJYCyUyDopwfOVL+WUGUi8W/1 +RCXsBnGDBBTfCT1BUZFDcFDhuVxqXYqUeOWD+XpJ4q6WBaWXzm0dlozIurCl7Lu2Rr4VYBWe8zxG5hTnc8W1AyjaUIxLxKXCWVQRbn+UxfYQ2EXCkuvmSmVv1kmvkSQFgl74xn9+7JOVbGWHGa78pXyR7ODZADxJzSgAE1B6oAU0RmWhhZG1RjTKUCBUQOXtWU+EXVfIFAXjhHwEUKQXPGXjSWcUIM5zsJjj0hsMVTDzGrALQhu2Ulmrn2VCsRAh -mCOV3Cx9jpwaVFOkW+VhBWn0IU3EDk5o/DpoVpVlEF7iXCDBWyijEkW/Hnzp4d36PGwWKVwU6KhWNFhJ5ZBnlOiXUOXomUlGUewVqUWjXhAUIgxAKaIcJrmaVo/KzwTuTrvhgupwuAXgaUOaXDEU44XABVbbHmY6KBWbeUp0VhyKLmJuj6oZChTn2+UhZn1NRddQHKX0iUC3BoBWy2JPqWR7HDP5XeUUmorJEY2L9SW+Y4RhXAkoQLFD75hhV5yw +WiblPEXcl45UwyO6yZbyO6F9qoyjqADfxwCGLREDl8q9dxzWzRDhAZgc3pvmX5eVpoX7HnauWleVyBbiBXmyXbiXYEgaGZyJTo+VuR56BiaqDY+UCTjZ6r9iWdEVJr4JQ6+RmF9rt6jw1z7OChIzBaA8lx0jBhFCgQQ6DxTKWG+WLiVpoXYuVKhXIYEleUXD4weXG4XpqXAkmSBIvliY6ycaCaXHJNbNlJ5zDbKAZ9nY+Xt85ngWkgq0zD3iVe8X -nVmFMU2EXKuGvV6NzzM9mZ9ztvrfkIIDLsShHUC0RBoID3DrZYWsMGuFJ1BXoEUD6AcSWweV8pF3qbwblBGWluUbuVmmUbKWASSinI5HhLEUv5p7qW4wTH+WCRD+hXN7JS5ZKDYWf55jlri54E60xkry5zz6rqJgl7SKkZgU196VKXW8UhthtCUGzHTBXP4WSZn0IWW1GuTHnIWLgV1BbuyUB4VijKrhV0eX1ylKfiZEB/1AD7y3PzI3xbfIRSqu +MZZ6aVvBZGWajEVfkamplXSlphVVvl7zqxo7ABroiG+GH6YIVypgWKPwVLrL37ItS6ZabRDhpYSjdzJYSiVz53TlHS5Ozlyy/9iPqW9+XgOWDuX9SUyQWV7nZ9Yir5j+XIBUT+VkQVmkAc5Z1cQRaXfplxGrMgzXYCjBXshXKeWBP5S+U0Jn1DkYVKyQqOuUJPyT0G8ZZIiKTEpy+Ku8R68H00VegWEXarpZ7zreArjGVNSnG2y7EJzHlEpni5og -Cigy5VsE47k6mVeGUjQXp7m2hW1sUwdAF6WtBUTIXIeUqBXoqVDaAPgB/ElghVtEYCK7sYVQhU3iX2iiEuYGBVDEaZCQ+CWaOX5aWrWGtvkXuXVWUrHZekXAcVjTafIJWXYI+V3mkCAUsy4HHZ4WzITmSIW9qUIyznRmhCWuYhsdyt6iqIKxqa9dzOazPOgsABvRzFDB3TmhpATgCRyXvBUchWfBUFeU2uVjvoJyVfELr6XKyVmmVOlljoBaVzRM +F7pEBUCLwABV6BuBbr4LCKhOxrE86kBBNhUauVL2WthVuGXswWpGFZ+W0hUytmbCQLwgmeGUSUNAzyURVED12VjBW/WX27jPiF5rnw/JebZzALxyVi8KOVrRInZF71OJQRXJWp0dY++X7nIEIKgLmmKUIZk5mkYWUk3JBiDA1qgHILFy5/SHgxa+Sf0zZIDXRJHej60Up+UdMX74JtBVbSQsRFW+V/hlJWWbhAigD9gmEKyDeAF+k58W5ex/DkAh -Q8zmbX5wlJSHCqrDNeVaKW+hXAs5neUxvYolEzcUN7keGJiCnnuYgEVFYzcskHNlemD31iurz71SoyhjIAHqAcSCi4zXXCMSX2gVAXnzeUfBVRHDAOUwjnHxkFDGyPk3YWpRlS2UsmWFqXKcxHrDVuWlqX9eBayLYBD1+VY2XXCVVqXiBgnKWBSk1Hm1CVx7EFoVKByYCHYdFlJkElaAEaHN6xpHN5HRuX08VgllJjBh5HD+U5njm/LDACfNDngw +VfyC7mUI4G9nkAkWTTbRBXvvmCRXbwXNflBkSdKUlflASULWWoCW+2V1QUyRUAHbeMUSXk7BWCaXwqFis4dDHfiUgUXSRWBmUV4WwRV07qfwUD1mNz7ialyRWcxENz72cEArnFBENWkOuVNwV/sV+MWh7kL8H3QF15GiRV/j5K+Ws/4XtFeqVU2nz76EBG93ncJly8wJtBswL52DDajVRxsODmjyscx6kopziNhVgOWPhVT0VCvkWBU5tHiKWlkA -V9Q58D3sCx7KUUg8XhwKUE0W8aVF1SnsRlhVFeUcID2pKb+Ul6XbqUQjx1aFQyVNvTFVKOzAmeEpWXQQU+EgzKpwhXdHEb/4jTH8mxbHzW3mp0ysBXB4J+Xje6LYXw4Xpomocnam2W1GW9eVP37SzAKCVMlglawrZydHAfLJioBf8gqS5jAxvRxOqDpvmgaWQIXFhXDEU7FkBBWpjKnZl5rkrKVeaVQBU27mYFC5bDo7BF9GMB7wXHhMXWqWd2Vx +rcVdBURYUoBW9BWo6Vz9QzGYvSxF9EkbD7MrY+WPZTBeUWf44M6ZyWQQL6iFsmWFRWdILALko4plRVk5E/nzxmWJeXaH6RrCV6CMtLXIgMXw5EDIEHXGAfiwrLxqbkpZjc67LeVF1RW2I4uVnD6uCLehWp4W+hXtUk+2KbgDV+y2ElFdAaDlQjQKOCn2Vi+UlqVaggg8jVl7dCUX6EPuwDEZP34vNqEgpsSnKbySgKCLS7RVQqVNuUsibK0priQi -aDNEG1qVyQbG37c/nVXlgjb8TbjJE9KbZ0w0Blv84VwXxo4AtG2lJCoUh9bTTTI/k3CgPTREoBLFxkABIoBPCidgAHvSAZAhQS7qRhVm+BXAMUUEkBBU+p4OhUmIViaVROUSaVhXnkFogtn7+WOaEj6hRuShSUuCpQmVoJFtuWt6Ut+WaAXG8UExVStY96WfaV96W0aX0OU8UTfpB3yCqUBTXjBHzIMAXULzTBpED10jg6XUgUMgUQxXoEVABWFe +gDvbTFOy4Ejm4BLpwTYA05BPrK5mWL2VT0X6qXhPk9yVGrYb2XVjmv8U9BXuzly3wAgSf/b5+XhTDTyTVs7Y7FHcU8pD3XZgCVTHJsNmoUVHb6yOWGOWlkbGOX5Ga2eo7b7NPZMBHbbqc1pX07LCXDxkBOYAlHYiLzNl8HKNuX3bnkko8IDpcAsjB0ORiMI+yb1MWRqRc8Tz3iMwXaqWgeUm2VauVPRWG9GrgWvk6vRVVznvRWPWVxfko1Ko/wB0 -VdOUBQX5RVVeWPYWNrBXa5Z6oSuUJSAXgYHtgCRUN+VyuX/OlZKVXEFIknUaXCoG3qXPCbsxG26a1WWRl7YgVA8Ux+XJcC5ZnY1R31hrpQ/0zj+ja6jPGB/Nh6opgxXpRVZ6U5+X0RXWeWmO5reV/BXU0nUrkDZIWACpibopBNNk8sVbxF/RSNIAyuUwuWSxUHEwySWGEUeVHz4FJsnV2mU/ahK4Y7LKjTlXkgaLH3k9SqdqVzJEaHY03luoV4+D +RNCXpVYLpLZFCwJhD5kXGG1Sxy9nCTFOGFVapL+FCH5AyraLaRr6g8V3uUHRV4xV7pnQmwioJx1KtmQITZnlTZAJ54Ao9gbgi1aWeaVekVy6WWwVthVZxHjRl5iUjSXbeVqhVvkVH1TyEWgHi2bhuwX5+j2nDPNnAjkXGHtI4vwEwWXYqZDSIs+kPcVPs55cXElbxkrWgo2goMWx+xXk+WwnbIwi7YAscyg3rioBl4B8gB3sBHwAOkC1aXkAWQBV -XOU8UTjKhpEBZ4B0GxeXzoLAnTmCMwt8wZElVsGuHmXhVpqWdFIBBUsfTdMUUfkxKWsZC8KgbarADAIgXCxUeU7PcDjMWYxXGQCnuWeuz+elOt5QRUF3nP8b+UpCoXvIAaxXTAQhcR/jJ+9mUrR3tCBaD53QThqJqXlupu5DURWUmVsSXLRWNBVWIkVK4UWUklmbRV8Nk8dL0YSeHonCWznIqLDQZCpG7ixVORVFyXj+EdbnIRGmBUC7mWBXogVX +WUC0xWOeX67l8pHi+b9LmssXmmU0hXqhX2BkaFp6AV2ITvWXjySpKHd7kcdnY1znmZTBXe9ZnWmebm7MUmGXc3QHXDiUAXLj0jAwkgeSQigBZgA3GBpjm1aXBfmnWVy6UrOWPBVrOUg/kzqU1CWEoU53YM9DgK4aDRdLFxmk3IW24j0JCENnY1yb6nF+5HOIE+Wkt6MDnUZ54OXM5HgmUIwn5sYWIRiADmjy/awYWDl9S10y3OIsSBXBU6mVBlT0 -RWiYVGZYdl4l2lI4oGKVFnKqmG+t7wYXecHU+yNZZ6en6jmdHGd6W3dqMaoTQo3UFiUV3KUlEU/xXCY7eyk6mE62WZBlGTkVZpZcUR6W2OUx0AgJXUjlr6SPtx1VgmIgLXi+7ypkDrARP+wDay1Kr+WUQaU5+VVsWWxVk/lJUwy6w2xXL8l2xUsfIxLS8OiXsTCfafmUBlHbHhHuW/hUZKXb/AfbnJGURbJG35FKVhHoudAlWVzmXHIVabwUnH5V +OUNaWauWkhX4kXHamhez4uWweVm8V+hVjRU+GUqkU8+hBQl7UX1iV94A0uXjhUr+XY1xXBBAFIgxZ8yUpoErKohpEFQWMrZg9Yg3lDMEy2HsQF/gVIdmhoXkkpSHBBAxOrzXFKG5SNRx/9joLDhdD/6RCGWOGU38UD6VcZguzAxRUcPzsOWb2UTuXb2WfRVdkWkrr9phke4IikGm7MWACxUSZy6OGncV+XgGQWnwXokKBBXMxKdQXpeZienyXItq -4Dz7ucFqeYm2W8JU8JWqsU2OWvqXvQXInlW2U8UQFBDtmQglB8BpvaxiGB8GIc5AyACxKA+OVt6Bf1hvBWTxX/TSDubQ2WfTk12UsRWQBVLxVAxLDZIu4hYUD1eU6rhOgTFmXHRUKMUToDnkBf761RVt9Hhl7E6UUCDPDmG5lp2VyXbSzCTSXtZbARRSTCHUD4RzuZA7oiy4xRSrjAD4Ry7sFceXshV+BWk+WuYUy5ELrp2eVTVkl+WOeWlxU1ND +Wv4Xc3S7vLiUABZDiGBVwTBAC+NzUjwvixnDzxUU6mVXZQCBV6xVJxXMnlcYnZ9YEJVvRUJuXJRWfRUfkXsyGFtjxDJVm7S3Jx0k9eTFxUKJYKA4Pin/wXmKB/xXPoLbEJl2l+97B7FK5ZGhnoRVY/kPp5iuXNZZ7zppIrN0VcqWYYaLEIIWKFump8zyabIRXRmUghbP7qzAX7V6dTFxsWSuVvPlrnAjgHtBx3bQ0rTcfB2ewXACGiyc5CP6UxXm -9UF0IQ4EDbpgMWWfFwi0lyugd2UWJX7yhCj7gqksaLTCpEhXNJnf8XwcYEILP7rouUs1piGUNz4WPl9DkiGWWZbFJX98ZeIVVJV1izN7kYznBm7xkrK85d6J1iETvl9TG2rI8E4tuWlJk3+UoPTBhWR0zTxlktIi8aduWjJW2WUiqX9uVRUzroUg8UGLbaFASNwwOj7eiumDoMBt8zrogBQTrYAkfJcuXTKUlhU56WdOVQXljGXrnH4JUYamEJU/ +dxWTmUQeWwBVXWWdmFkwRpxUkcVb2UWmWfRWsUXzRwSXgQkAZuVd0I8K4u0UyYWGcV1DEUTJF3GMuVBU6eRVwhUAXmhjkBXZrhmjLYmRWMvmLl6UBU9GFYBI6XLtJX+XkohV5UbqmZFJhLVJjTAU9DIEFBKDRxAmWpNHAEhWXOBJGBUbnsZm/CK9RXMagGqU4iXQ+mmyEJ9J0RU4Xm0yWNeDB8bOxqb4RWUWORAUpIVq6//gCxXguSJ64GJmS4W+ -PL0OQPQJFgp8kiesVKOTCQLbxWyuWHKWWJVJu7sArlyXcAoOqXU1oQWILqanzDSCFC6VRxXRcXXJkYrwmdkULQ/JVOd7d0V9RW2OWTVACBm73RlTmtTghtKLFm3QZ0RCXsBnGDBBTfCQAXk46CTwWC2VXhXNwg+2Uo16BV7ZqVn8UVeWeSX5qUurCl7Lu2QCmUvgKe8zxG4NznUJWlmW1Azu+V3xItAXzpnrcWXIU6pZf6VAJXVimuymmKFy+VHO +nln67B9RSRVfv73qmqFzbg44fkdsoz5knYVbjzp8pAsk6sl3MbYxk5LHWNnWQ61Rmahk29nO4WSzn0H4oUWWQaOVlvY5vvkRkEXmW1RWHGYngDPIwFrgqsi5ni3Wi+5wgZhTAw1WDiJUm5mutl1Fkt0r20EqxKk8XzJXdyVKD5dKGI6VcwU/6VDxXLmW2lgwhj/sCGiWVQGTN68ZAfxV1JqN2V6oK56neR5/GktUXTqGUtY1TkN9lBeFAh6D9mtn -XZkVSsn9+7cFaCl5UOWkxU0OXCbyVZndkwablbiSyshsGSVBjYrkE1B6oAU0RmWj/0X/EHkGW6RW0RWke6G+XLqWzxUX/ImRVCMULxXPhXxZacUIM5zsJjj0hUiVW0bGrALQhs+Ut+y7xXvJyK0EYSWPswyO6yZbyO7YgU96I8zFjqrM9ko1B16B+NypYTK0rPsC9dxzWzRDhAZgc3o5uUZRVLRUGRXUTkUrlnXiqwW8SW2UUSOXYEgaGZyJS/dm +599lAj5gUHWJXKxqokypekVNmetF3nkmD75MXKRVb+DSOrtnm15Fd75FGqGkXR2XgpV5UYEyDOxheXz6JAvayZCzPjwPtCCfDW4DWeVpOna4WMB7/vIU6lCEVGji2uJJpih9L8sK9LmwBjvhXqhVAWXrrDvmQTgAUrksYKGaSHnD3cLTxX1IgXeXrNZcSVb8UrR5CamaznsclKKku+785wwUWDzFLO4A3k8B4MeXVxWBfS09ThKBUyD+mo1Ei1DR -HgqR4AbzqYxUCTjZ6ps6GGAVJr4JQ6+Rn84ULLnHGVOqjt6jw1z7OChIzBaA8lx0jBhFCgQQ6Dzm6WmxXbJWABUhpUHPkioY7iVkzZF+V4pUxJXtBXAsUvliY6ycaCaXHJNbNlJ5zDbKDBDmYxXt87N+UVcaDmVqRbxSWfTyTmVvBZGWYu0VfkamplXSmzpWz+FiIUl3kxrYRLnUZ76YIVypgWIKYVtS6q2IMGqP0UP6LOTTKrnRDhpYSjdzJYSi +CYzKUAxbYv65icVrjkgJgb3DsbCMXEFeUoDnYpVK6UAdHi+YEqX3WWsxWTuW9BUbvnJrks46XIm5RmV5TB7CHUURHl6oJTRUMgmjjmKenb6XC9Hmia5TlALlcpW6zwHRk6LaMfqejFTz72ynFBXeA5a+ClEjslibRjEoDbbJnu5a8USNyiUCRPIFjlb5aptgzJV4tRvlQmpXUrlF87Fnn04U8wb7TlfSW42UbUV1drmITy/TaQgqsQIinZGAf+wH -Vz53TlHS5Ozlyy/9hamUTxVqqVTxV7PkLyXVYTDQUmc4+gU6pWsRUJVlmkAc5Z1cQfmWngGc4K2RaOUCYxWyYjgeES+HoBbyhX4i7I+EVeay9buoXi4I4vY2tmWySVwWEXarpYxcUq8ZiRVYOX4NHbEKx867EIe0VRUznBWjXj8UT5uLpEBUCLwABV6BuBbr4LCKhOxrE86kBA3pXNaU5+X3pUgOU2eUyPm8xWoqXooA506OGlb7nrWXN3ryURVE +JUyNg8RVxIXtQ680Uee46SoAoX6Xp7A5alb3pW4xXS7kk3KvJD09AZkRvwijKS+eA+eA+IBHwDeaASPlpOkUUVopUZM71kV6qAK6VkyW5pU4b68YW7EVWpXmxUJfmV3nAfDGsg1AU5qCk1hHKXFxXzVTNU7pcVr/5Z24Tt7Uam9NliFneyXpkwt9LpzFkfrSdm07kmF7QXGH2mj7GjOkNNljNmL9mzzk1RUgKUuN64agUjAG2Lrtk0CBwIAoWC/b -DO+Xs+WwuU0tSEeVbvGI/J0dY+rrZF4gxZbaV1iyFump8ySpqhuU32WNqyOVrGmEfmZvxUIZkkxVCJVp2VCkCD6U8URBiDA1qgHILFy5/SHgxa+Sf0zZIDXRJHej8cV5xWQxVWeV7JVZxHBhGMZUqyUigD9gmEKyDeAF+ktSW5ew/jlUpWpWXfGD+uV17nNRXC86TTZYSVGPm+ZU8YVlAVBkRjpVLQaBZX7HbPnY8+VvIUorle5rX35pGVAoU6cb +a41AgBBH/aRWXTJWGpU7IVLzzLpV2birpWGWV4+pw+lbpUkQU/SW9hWDWXpQLNrjUJAkKUbaA2UzFJWupU01Tr+Vr/6tQ76ZkWRWgyH42pCz4KGm5EDHchyADx1AKjjwIDgmwTaheXyL+TuQUTJVallzpUGpXLEGoorhfkO/n5VFQZVX7FleUkmVvBUV1LlvDHxIdEgXTm7QU8thTXBMkljhU0pUr+VGoJljKWMbb25jMkBzbcH4aYWOVlIeksLk -4KHobJis4kBWWBG7IV1xE72nMpXOSpMBbZTa32Hu6kRZV1BbwmWagXzUVM8H4a5LgXfCVw56AnnXCmP4WaZmbgVe6Y3IXHBU+RUXZKdvnLJGuCX/sUgpX02VcBVM+A0uVRRVy8wJtBswL52DDajVRxsODmjyscx6kopzjXpWqJW3pXAMUE/kBBVmiKQMlHJWMOmVbmn0LrqQilY/UAvSxF9EkbD7MqYxWPZTl9JVx4tzx8zqLmrEQUJPyU+XE7o8 +eNkMrmGFzv5Y+yUfVHaRWZLowkhAlCo1wgHyfhilEheSzCVQuADkIwzpVquX8ZX2ZWJkDCZVU6CiZU0jlFHGdBWEJVFpXEJXsxXM8W8DxUeRUmXqPRpezd2DjuBD5mnJSUDwkiZijkdjHJFk+KoXJVjMkW+Wrf6gB6oA4u+5qlpiVHl9lelnieFhpVbuW7Rn+GlTskdnaiB7AXauiXSeH/w5gcbLA4AWmqdnAu4bTyLOkbTzMh4UBnP1lvqkEM6j -KyK5w/nxk5HnZVUeV1EUxeUtMAQpWzJWjXiRrCV6CMtLXIgMXw5EDIEHXGAfiwrLyj7kpZjc67opUK0VW2LfBXdBB8iKwxXIyXKBV6pUvUVPdZJJVASSyjlQjQKOCORV3JX0iW7Un8ZWiTnaXmkKEJDZNvZWq5vyW7/m5umSgKCLS45VmGUDCVCpWZQjxxV2BWjXiq+U6oRrqTIBDsgBJTTcqLukB7ciqgKALkTwWh9lZ+WhKUH8WgAV+QWCaVap +rJAB7ZcnWSrx5njZU5aV2MZtpXP1kVXpO+40NnWQ4oZEKGn+BqljwAawprDUgDwACCBaWBJgtglyRYGVaOl6pUoOgYnClZWcWBYcRyUQQZXu4isnmj+XF2WXFnKJXsxUV2UeKgLyhj3z5xV23GA2CdZVoBzcaVNJYJQXtWlUhFTt4KGnAQTAKJfwC+2J0RAa97O/hDsjnAC9uW35ma7lP4y+zjWvZCEUiljlZVmpUoF5gM4wZWSBU7OXzKCSmTjI -giOXVhUQBXmRU2ZW00WFzbARL2ITguXS4AcdAGsgexUu+VexU8pD3XYkyXOoWE2XxrEd+Wg6Fy5V3Io7uy2eo7b5bcXDxnt35Q0ZZxYYK6fyUYK4BOYAlE06WG5V8HIJhXWBVE5X96WwqxP2WcPn3yAMAS4WCRlAUng9vaZhCRqRc8Tz3ihoV9GXNMUQ2WBOVchUc5XK0Xp1EtBXNpVtBV5qVtpVqWGaIFMaC9rBRjmse6eHKwJi+zkXGG1SxJD7 +AYEWMDBmHHf8UMQW3KJ9nj1Sl+Gn6EV4pl1GFmpm5N4FFIJHlF0WHwXi3lMWGwj4AHaJ7m/sWd3lqu7K5XypWMZValFDsi6DxOrzqACXgCk2yziA7UCblhXaS8ZVTJXzpUCZUBYXAuyM5XGf4G4UMO7Q5U2BXj+UfRXsxUkuU32BKtLcEjc5ULKDl0ElS7o5XKP5chXM+ogoWhdE8ypdOY/T4qir1Vk9w6+oWh5VEBlfOVZlHDQwmNZSjlPb5L/k -IPoL+Hgo7DBpCH5AyraLaRr7wSV13momV08WvrlahU8LRmHnbhWuYgFxxJFAsOWtmQITZnlTZAJ54Ao9gbggD6jfVl6+UV2WrXk+5VpmWKUwPhUB5VPhVvpVLxXLSnZmokVm2bizoX5+j2nBFtnmJXb5kXGHtI4vwFNuXYqZDSIs+lfiVPs6vaXXN7xkrWgo2goMWwL5Vg4XdyUXtkOWUUxVzlob/Yscyg3rioBl4B8gB3sBHwAOkA15UCQUe5VC +1/7RTQdWCCVQLYD1DAo8qY8KyXRpRbetJH/amwUCyjKlh05U7IWSgmW5WVZXKBEuZUBgCs5WoBVGuUu8wKJa0GVDhWxXrDIijGpe5WbxSK0F1+XFWUSfJpuln6HnJnaCFkxkTc4AHZPYX+FniaYhGnLlEd9lH+nSOUMwFssntBnCz7BrCZEacABgdY3BLakyU5DhIz5tQY34rP7BfklZWiGWGaHm3kRfkf6k13JFAVW2VJRU9hXxZaVp7tGWn5DY -2U5+W1pVJIWr0XpkJVhXGmW85VluXvpU70X/LQ8Xl2IT1eWtIzgmC8nmuZXcnnY1znmaCmVxLY1b6gyEX7kKNkYRWsEWMcVz8X8yn8Wy4bC3yBam4eSQigBZgA3GCVTk15WuAXshUV2UNBW+GV0mWNr4vl46JV85XUCUM9DgK4aDSfFmBSWXXZH7j0JCVRV4jnY1yb6nF+5HOJ06llfmtRXM5F5OVouVJW5uoUNzAP+V39D5sYWIRiADmjy/awYW +7G/hXR1mJZrKKX85XWApThWcgFtVEX6EVRkjI7z+4sG4yO7XVmZi4mA7i7HAu6/0FAB5VhFimU4UziFJWpmvIraOyXLgBeASqCKfiFUmCVTH1RNMUQNCkWU05V55XNvi89Rm7COZWL3l+QWkUHpJWPGUZxWI+WSBXTuW8Dxcpq9rCH2VmkRFXlFJxX5VYQiROXM7EPe71fxU1lSyFssnJrYh/SjTmBMXPuV6M4h/QKtYFpldJWMBXaH5PsDGgCF5 -Dl9S10y3OIsSAopUZFDgDA8aXcuVe5XmZVG+W7SX+5nzZX4VlQ3n0ZhhEpntqZohBQmdsXHKV94AS5U8ZVyuXY1xXBBAFKiZWDMEH3lkhEhpEweFP4VBvkpa5HxYNyWgLEDVEe/QbdlOJWXOVYBULLm1kXtZaYUBBAxOrzXFKG5SNRx/9joLDhdD/6Tz2X/2UBWVL2UuzABBUcPz+5US2W35W1hXvpXShmBAb9phke4IikGm7MWAx5USZyjcX0JW +rg8H/RAaABzPEUniDKh1KG0znpBQt74VrgdsQbEWemGb5VOZWITkmOClmXuZXJSV24wZICkFZ+biTN77KWyNGZvHIMhe5WUvDnpW75Y2PmcMqzTEydlEg7GIXEqCXPlA2zj9zS8q6bT6pkUToGCkUTpy6GDEoxZnBnZW9lTsnN1HwjlCzG/5UE7mYsWVepb5kyl6MGFOgphKLqzmyiS+FX2CEJeXq5WqrGEyAYwgU3ICvhSeTPyRNsxjYCZcBb8Q -xWqlfof4VaNFhcXMxJKSUKmBv6XyXJZ5XJUUQCBqeDWGWZCqhdBmkBX3wrLz2NBLAAI3wvixnDxmsWhpC+mkTZV5eVTZXn5UL/zhWXaSABFX9TkbRW6pV4VbjTAMYIFQDxDJVm7S3Jx0k9eQf5WkFUKJYKA6ARVljnZopaFU6wLoZU3UGwiGYlYq5YKZW+GmNz7EhXNZZ7zppIopcXALJs6rOyWgQISZVWgoNXpLaX+qWV1wlJVRoGgcVxaV32Xg +iPF8ZWm5WlZViHl4cULJUrUXR/511mSZV4PnSZWH5VMlkMuCLphwWhq/anHgtfCaFWy+jYeVjjkVNlvVG/GkLXlUbaRAVyqUp0G/NAAZBQ/DYdhfvz9rpQtjmZV2yIiPF8EWUFnopX1kUW5VnXErpXn/mlaEvBWFgXBaUKFWeeXFjFOQDA66WgX7syiYbFJDzWCaFWMpo2SVhn7SCxOckkZXRFkonkj/l5tmrLm+DoHuW614gpVSzlrQomF4LZWO -JWvqULLTvQXdZV8mJrnAjgHtBx3bQ0rTcfB2ewXACGiyc5Bu2UiPlIFVe5WxyW3hVsJ6I+5leWKyVBFVOuV7CXYflcwS+lGWqVBMUsYK/ODXcymmgkFWf2a2oiJYHQ853xX1mXbCGsHFmTZ07p8JV68VcJULOlmWU9GFYBI6XI4lXMPkqZWXOUiJUHgWgFXsUxrLRu/iY9YU9DIEFBKDRxAmWpNHAKpVb5BJGDJ7nsZm/CKZRXMajOaXxFzQ+mmy +VndKUEZXEKHUBxPSFhmUZtkmkUiQEf0We05Lm7l5Ff5YzI5aZkN6URpXo2EqsjE1QiyqCxJ+NxaMTaCQ1EhozpiQVa4WJFV2ZXr5Xflw5pUY2UtPkPLmAdG6oV25XdhUO5WT+WTrmxOBE8Hk2WC+WG6AAuEKBU5uWlJVqcn0vBYOUcjYTQ7d6Fl9mqFzHIaXuwI64vjJklUDpWDC7iVSAMDzOA0RSUADBaA2ubRvR83QY8o3rGlgnTcVAZWG+7/T -EJ9JeYUcelOeVtxDB8bOxqb4Q6h43EbhKQVq5yeUDFUwlXguSJ64GJll1laJG9+kwZVUP5Mh6tQ7Y3Lbg74oUsIXbAZFGVePlAsk6sl3MZv4Uiam8anscm1RmahkqDkQUV8m66A7/0HmlXW4UiH4LsUTJUBmXBFmWg5vY5knTQDnkgCPOgm4hDAAmMRPLj6+R5RicQDetKkOlKoUKFkt0r20HoyWkrnLeUclXphozBkQ3m9OX8LnBmhqshGZG9JE +QNOySFXIFWmO4WpUP9b08UnIVEuV4VYXxqNqTp9kKcDYUnMujN0To5WCORruWNEqQcX1jEpJGKpFQqG1hEJZk4pFKj5CBkONnO4WcXIApVRw7QlUkYUOSWXYXHYFGlXbkX7KnB7IB9nHM5TcwP9DEgyEWAhsislpFHTzFxJSrAwU9FXAZVclUx5wpvkZSXexk2s6X4U7NwrJWkkWPCXrJXI+XSI49CDfkUUuX5ijUTbRuYcdmQO63PqMGXbg7Suo -BSV2uyAqkChyPFl46U2qV6oK56neR6bGXdTxUWFqlYRfkSJ6ED4gUGtn6StlAj6e4WrFU6gypekKtm+flfakhkXYuUbAoMt7XnlyJ6jwb/T45kXNlW0cXS+V96U7mWMcVDRWntwZri6JARTSZnRdarunIPtCCfDW4BaRVpOl3kWMB7/vIU6mmUVGji2uJJpih9L8sKb4WNXLhOXTEXwxXtFUVuWC57vmQTgAebksYKGaSHnD3cLQlV1DH1IjI5Xr +CB4mF7RMXTrFCTEadmMxGs/zDcFW+rYxU8CQ9PlBHEWVpuzoAI7RB7fFDhDg64jX47brQXIyHxIohxXyShvQ6pW0znslUulWclVF1SSgk8lXZgUvDnbn4nZyqhVJ6XZ+W8+VK1SEvFYUDBP60CgkshshXBZW/WX1yhjGb+rF+5Wb7KnlmFBnAcVBcHtR6HuJY1QtvAcplhxDfgSwkhWsIlcCk2xHxXeYW/flA5WDpjr5WnXn7jhM5V3GUWpUmyW1 -NYeqXs+nd4ZsBmzkqCm6JLlH+llumNerv4U0/bTqld+kyB62lV0HlefJhw7YRUF5WxrC09ThKBUyD+mo1Ei1DRCYzKUAxbYv64J/EMlUgJgb3DsbCMXHqJVQaVw6UreWWJ58zxuSXleUtpVB5WAlVbuUuqEs46XImEPlTWSRpC3JWexX3JV6oK+eUMglbTkrhXEpktio2dJyak76kRL4HRk6LaMfqejFTz72ylXZWR+Wg+CcpVflXJcBa+ClEjsl +ZVKJUH5UilV2+Xa6Dv/7r0V1sVonywzAC4jUpWpZqN2X1yixYgJJkdeWOzLUH73uXahlRFlH+nazENQ6pFIIlwVDl5DlvwVkxk/KX5h51DngjnU8mUEB6I7R1IQXJ52pdsxt6iXyCp8CbzIaXm55ViFVulWzbno2VLQG4rm7EUjFVJSVjFXlAzHHC+MHM+juBUIInctGmHgOyVYlXmiU4lWWBjPjkS/k/FmF/Yi5VkpmLWH2RVZlE2hlRBlXLk5t -ibRjEoDbbJnu42SUSNyiUCRPLNTlb5aptgslV4tRvlRzlXeblF84/BWXYU8wbr0XxwU2UXQMVMZWoeU8tSl3BH+jcRUo7bBDzuy4+hXoHl6oIN2CEjkP9kW3nDNm+CXBR46MWmVX6Xp7A5vZEvWWxCoYzwhCVsVVeiCvJD09AZkRvwijKS+eA+eA+IBHwDeaCaOl8nHvMVHFmBlUFYV6qB7ZmhlW4iVF2F6x6pGHWZXYFVieUYn7AfDGsgi5XfsD +mOIwmBK9gr8+z+wK3lSqFBUPzHXDx8DiqAEuk55WiFWZpWNlUDlkDFUiZWE1LrpVVZWZFU42VSZV+OXxZbsgBkIbvmLKHnPHkg2D3G58iwylVcTjryoGzKIaHC5V14z95Wo5Lj+69DbfIUAnaUFGSGnYRFFCkMd46SH7d45hypAYyH6FLHB7ng0oDzmWzIgrmN6mr9lH+m457RZVbxypFmbd4X9leRWvJmXnSZAD2WhWdYAjSHUCRiB8nIxECvMj -s1hcNQSlVHlU3VE0EUuOkTt7Ualmtn2FmPeVJ2rr1bHBno9mQjLJekzJHStlMVruBqjOmatn2tnytnHRldZVIWXM1liJVMli4agUjAG2JZdk0CBwIAoWC/ba41AgBBH/ZceXMlXTlUSEVLzySVV2bjSVV8rDx9m/FXgBVEiW6JV9/n3lR+pbNrjUJBe6UbaA2UyqcWQQVqFVfPBeeFdSWtQ76ZkNWk/T5cnZBJ6D+Ud7kVyAHNm5EDHchyADx1AK +GCUQNBIHzppW05XwFU8MD19TNlWpvk7P78lVxuXpxWZJWZxVvkVK1oFUXIMiW7kBGX+fB2W6reFRlWaVjTKHvNkWylufls6pQdmLZVPJX/JWqIVApVosWQgXYg5PQUtbG6zy+GllBkbhm6zx+hqHYVPpWvPnbKIe4C3sKgpK78rO2qkyBn1STcwvgBglCLnl6aQRSAbZn1lV/ahclVTOQyVUVZX5wEToU1ZWKJWmxWdlXjSVGBUzukiRasYT5xUR -jjwIDgmwTaheXyL+S9IXoDkFlkiVVTlXLEGooonfnugX5VFhVXMRXr2XeMUa0U53blvDHxIdEhoLkuxW+2HYzSpgi+zlGoJljKWMbb25jMkBzbcH6HEXHRlIenermYtkBbmGFzv5bzaXdC6m5WE5WahVFzwYsHqkrGDkwkhAlCo1wgHyfhilEheSzCVQuADkIxCVUfOU9VUPVWJkADVVU6BDVWwcCKcHhXl/FXjVVYFXvpWCSWq3hUeTDOXqPRpe +8gIYRDlVPlUhZW76QESk1VXAUEr9kVFXHRl1FUjeWZglZhAYjIvwh3whOgxx4YY8wrLwW5RRqWlgm7AX6pXA5Xr5X9BjrVWHlUxTE4VV23LMxXxuW7VWJuUkqUIWDgZTA7AhTr41m6dKQ9j8RApLlozlGBjlPZcyqxozm5ERQ4yewFQ6mIVBJXbKLwIC78p4ixaEK5NHmIRrERsdzeuCKQqKv7UxXLVUYpW8OSk9gg1VW5XljlBmkqwWKVVUhUCY -zd2DjuDA1U4eSUk4ZWVKDn0H4mDF7tn28VRZVPzgKUVUYqgB6oA4u+5qlpiVEpDkug7iblPlWg0qCVEqTnppp524dnaiB7AXa3HJsC7WQ5gcbLA4AWlE9nAu4bTyLOkbTzMh4UBm3lVvqkEM6jrJAB7Zcl7Nn7d4XQ4U7rcpUjz4u+5bzkl64U7oy1XdeWgpWvqWbA6m+XHgX6OGhuAARRGNIBZBWXJ1UJCMy/IqAgAMsreZoTlUoOgYnCU1WcWB +UKkUFVVkqX28pehijmAUrkf8oXm5MnAylVdEk2v7mVV1JWWWEXUWQtHdcUKalAZEtSEV6kpMyhpXj9ysLlaAaK1VM2BTjnJAKZEBNtxgHxp2COiL3ULucyP3C7sa01Um5WglVulVvqWmpUs1Wx6X2jnrlluZVI6U7pXZoKA+jgZTVqL+WRaJll5xYQiPLqi1UMUEk+5RuliAWC3k5GrZQ5g0aPxw8hVWkWwmXoAD4oGI6DhNxq4Aa+DuzzP3ADGy -TWVhlUXRE4mz2uU/gUoVXiOVMZU+SWHCULyhj3zGJVDUZVrlJVXZ8lBXB2cna2lMVUa6XPXmmaAHNnAQTAKJfwC+2J0RAa97O/hDsjnAAFhVaOmrHlP4y+zjWvamUUiljU1ULlWUUVpIIRVXvpWdBWtRF9eSRGUBaVh/K5TJnXkF1Uvlq2ckvwG3A6QTFIzk9GFSZnRNmaDJMWE+HHO8USeF1GGwj4AHbTPmLuHVioVQWJhW6aVCkDy7lOWWjXhs +SXQbIWy6kglWA1VclXA1WFikbVWitk5Srl5X0VmdIY6f7xPpFJAJDk5QLkxTC0Si1VZOTu+Wu4VZuZ3GFKDAKRFLy6QAUyB4hRYMBloaU9bm22w09mmWRriQYkCvnQgNBa+URZjzOVycm2eU7lULpX05VlkAZVWelUo15eIXPPLZ1XuzmPixy67MaXcxV1/GxPrJXC9GUlJXUVX/ODuYQNiWodEkJYU2mj9kfvFFLkzD5osVLWGOFV1NlqlHscni -ODobB/ebVOrCOBEyTvawFNTURDhLTLiXoDmosDUygU1Ve2XAuzd1XGf7e2mQ+aSFW+DknPmKEi4bCxAhKtLcEidUULKDl0ElS681XKP60pXM+re4WhdE8ypdOZbVXG4YHEVAEWLzmu4U6dk7mUV+5INWC9wmNYKTlPb4bhUM9nIHSaznRTQdWCCVQLYD1DAo8qY8KyXRpRa+lUrP69oUCyjKlgd1USEWSglv1W01XKBGvVXCr791VLxVKKW+SUKJ +Bkn1Ww0l5yQ2Cgj05RADjzxqfiD8n3GAE1DRAB7slPqX01V9FWEZEelUEQXC1m74w3xU+hV0aWqrkDZJMXiaTJgmq/RVSwZqvGpgjfBVUVVOWU4lVVlqeBkNoX3Lnz6DDDls7l99mPVVeuXLJY+mAL0R6BzR1AxgaIADaVCYUA2hrYwkFpQUkBJqKulWNlVv1X2/m8lV5+z6zqT1VxfnkyD+0FH4jYEUdrHIGrzsLU1AylXEVYwNVbBGaT4j269N -bt2Xfpn8pZG+iayUZJXb5m3KIQP6WZ5vWke6bKJ7flkt+kDEY3vpW14hg4Tc4AHatew/w7DQxjNnT+mlDlH+lYBVoNVu4XtBkymWOVn1dJ0XnBrCZEacABgdY3BLakyU5DhIz5tQY34rP6uAXP1X/TSGaFknmnfkf6k13It5WBFVM1V35VLxVxKUa9QwrLr7GMY74taJZqV6UCNXw1k2hh2Imlx5vqVhDGheXOwjz+4sG4yO4m1mZi4mA7i7HAu6 +lUNmgVXYpEcVFlRl2jHGtnvmkfvHjeymTlcVWPaXhmU7+XnukWkWjOndhptJmBgI8Wn1cUV8yX1rIBrz3ikAn3iw4agNWAG6hk4adFZ4WAxv5e7Ak1h47RxOBulXzcWW1XF5XBmkueXx6VTwXQ1Vw5W3/ncpiVs5V4TANW7oohfguXQzb4ylXBgxU2X+mXGQZVNqFCFvKWDZXvsX3+WfjHCeHHKoOb5ciUzZWheUo6YeoWYTrPnahmXhBUfSFLtZ -/0FAB5VhH7OXOQZNTGMKUl/kFBVeiDwbDhlBoWDI8KY6KWCJRxAvWiCVTH1Rv+lmLlzuVt1W0NXNvi89Rm7BPVU3vk4smqVmjVWPhU74WLxWTVX1hW8Dxcprh5WhgW1HjpqLmpXuXSLkU2hhyVlkX5n671fwV1lSyFssnJrYh/QPzkSOmYhUFpnGOWQyRbNklOVUMU3AV+1WrLQw6BZgBCGQNYD/RAaABzPEUniDKh1KGlNWErk0NUdsQK0WemF2 +MTlhFEgN7u7kq+VphD8KhDjJfFBaEK/fxmADsGzYEis1FH5WikVBPnJVVwFXiFU6kEQlVHZzZtFj6U7VWcOVmxVHsW0gCaTKk6iI/m+eVkNgOQD/5huNUUtrQ95B2b3FVKtaFBWQyT+KyXhyqDI6STQLZV1YZBXTnzdba0cygQRJ8TGgC16AgQTdBzxDirmgk4XVel7zloVWSVV4tSemFF5V0yEujzbVUsxVnlUIlVkQUNhWbJWfcjGGbUmVl5xl -NXPVUMzkmODFxVLAU/1XbEgZICkFZ+biTN7cGUyrBB5gfJTw5X4VVHrkC96e6VslmR2HTpmrMUAhpLab6plS8ppuYUTrS8q6bQAtUdEEGCkUTpy6GDEoxZnBnaC1WCblalUtFmEpFBHFt2HyLxpYz5EWqiH2CHTmphKLxLmyiROgphKJaNXReV31m6NU3CiHM6Ibwvfj0GyjnnPyRNsxjYCZcBb8QiPHdVWiVW9VXL4VpkBBVUJlqJ1V3hVUOxw+ +IJ3IWVVXIxg+5WAum4sZpr6nb7x5kqdmqaXHYXwUVkr601pnVQ9pX65z5tnGNQKKmPY4IjmdBoxqFRH7nyga8mNFyJGk+tGT/l7VasFX7BWh95qfg+ACiUCQroDbZ4EiI3b3bTcGSmJCXpmbYgGNW8lBqUHs9RfIDrNUUyVVNHs9Q+OXbpVL0VhyJRTTL4nowTWXl0Ca88wlChd1lX5UCwSXNWWNnXAprmEugU3V7pWGM6V/o5pc421611W7BUSa -lO6VwxVg5XtFXsRVLiCLphM+XVxXnhCnHgtfBgNUmvGvVFwrk24V3nmMmk3XnsJXGBVTt4lOXvIDdlVOqg/NAtzpmtAAxCcOAJSJQtgXVV2yLJrkbZkBlUZM4FYWv1VnXFSVVlkFbaFf1VIjnXNUyFWWRXFjFOQDA64ZwUHnn5jrFJDzWDitWMpoz1Vhn7SCxOclkfrUkVfr48+7TUU6p6nOVj+4UDFfJVMQFTYWo658bn+FkWLo4MXB/R524nuY +XMC7oNIc/YvXS7UAXeJCOCd8xPtBZhBUgAF5ybFyP8lSLkclUrVWNlWD1zv1XlNXgD56uXleXbfnv3g70FU3nrIRQ0T62bmKZ2NSPa4QNWCbk4lWSsQvv5XOVz8EQiHBMormnYnGe6DDVwUVyYAVQqF4FGy9am17AzHLjZM/bnblSFma26Bva5lWZNp9KUKGlELD5Yb10zs9CQniFQD3GAh5zcpi3sIVGUaqDTdp5qCRTjC8ip1V4QVb5VXxXdGo -aXpsqW/Lo5hz1C5yQE0uWub5gLY3SFcIbl5Ff5YzI5aZlTFlAFVPS5hrkqtVq6hhSDDAx4wpBoKCxJ+NxaMTaCQ1EhozrD3m3kUMtX3VUv1XflzslUhVVUBDDpIMO7NmmmRXQpnBFVLxWFRWysLEIlYSkTaC++IAuEw9SplWd2XkfCLEVg1UTQ7d6HJDmqFzHIaXuwI64vjJLtWl1W6aVbACjhKoNXy+Wxs4LADpgBumh1DBggC8OAemA5xxvhhX +dlUw1UdkXgmyo/wb1zMNWiHqN/rvCCD1DnVX/For1UJKSsAGQGWvDLQcVh1VBMAeeBYqxjgaYDyKQpMSA4fS5BDK6KDqUxWm8tlotVRtVSVW98X4QXHXg5cH4pVGUXc1W1NUnEXN8QI+S4wRhlXsaA1wiS7Do5XoITqZVptzL+y30Ww2GMcHTk6uVV8pXqwZoRHoekG6Z6LEpzRrpkVJmdiUbKlLDq9cGAtX6FUpNW+xBFyTw1xAvqDlZyayREpc -4b2AnamWGtWG+42NVZHBeAUkfmw2ksNUcHaYFWuNWTVXbRVK4A4/wZoVwOV5WlMYJ1OyHlVqcmCOSdhXizlAlk1zCSUWvyVQqG1hEJZk4pGjBVlBk5jn0G6cXL7MWWQaCblbpk3qlO8mekUE5UXOWUMUJNl5FV39DWDnHM5TcwP9DEgyEWAhsislpFHTzFxJSr+lVJqJGtU2NUx5w3tW/+kCVKCMW4EWHSXt5WTVWIxWDdA9CDDMVvNEQjrUTbRu +TKpJi6dG8BWg2mFNWwFXoVWNlWG8Xp1Wg1VChn+EXZjHw+Umbn5VW1NXZxXiszrLxiIQmSWHyH9HgjtW+lGCtHYuFujEVVkGtnkVxeiW4sW2147OF/lZQdVx5WMeWjXjzXyW5S5yRfvyVhDOa4euAOkAFwT/awKMWZw7c8CENUv2QNlWrNVrVX3tVW1Xe7p4njWBX5iXdBVsxW2NXKkXzRmnGwObAFvn5DgMWSPlU5tWQNUBfCkvFesEPnkSrE2y -aT1WQO63Pq92VQNUmQ4CB4mF6FVXTrFCTGk9mMxGs/zDcFW+oocWdBqlumZum6dlrc608XZFVGYWqUWXFWxnrz0RU0QCvh5Rj0gD+lDFBAp1QY8phiBJSrntXkdWXtVF1SSgmnNW1NW9yZPjn6VlruU1hUAlXRpX8xVK1SEvFGJUEKUTZhrfiXJXcdXckBjGb+rH8dWOzLsVmFBkAiVBcHtR7RPkn+DdxX8VlY1QtvAcplhxDfgSwkhWsIlcCk2z +Z2+gK2FqjnI55QUVfT55yWhrEdtkMFXGlrAynpr7b8Wpr4QoXvFUEwxucrqCoyeS2WhbZRcvg3tzwAD/RBYdXs8k6kFFNU3tWrNUV/lEdVmNWK/n4SWGXkc1UvtUIEWYFVs/kZkRwOQHljDWEMNU0+oZexSElX5Wm5hjtW3VWqsWE7lMGXxNWp64hiUtpX2PZi5WvMaBnn5hGQdXXNVzR6u7nsfl3SnXeWNxESdXltmOVUJrGfSGEBVFpqNYVqsU -8FV9EV9tmTlWx1Uv1V5Pn7jg91V2hVeTl23JNpXONWtFWMdVmIUt6jo7QyxB4IUftV7iAMbAC4gqFUWpVTMX1yixYgJJk0FXM+7UH6Rdmo65e0atDmpD5Q1U6coIlx/4VH+mDm4o1lzOnGZltxH9dVtlVkhVgpVCkDxuVq6hNziY1S9gryXQQXJ52pdsxt6iXyCp8CbzLvVnlNVHNWUdW+QXBVVSKXNdYElkxVnzxV+TkEpXAsXHHBy2X0pyLlwx +QUWk9mE1V+GK5CCiIwWADveY8GRV0hz+Si3RRSKU5UxWm3W42PF6cXStUEdXCKVZgWZVXG+nQt54VXU0l/1UsfLkswilaq4AY6WjWVMQQ30bpWX2dXYBC0tXG9Ia0FaXLktZ/wU8UE2PKFSEQhz0MyqDKDdWUlVEJ5E1AcHR7oguZDAZClEhsULwbBuzzo1CblWyfBXOARtVk9yDfBclVKNxytWm0WxuWyFX21WEtUDBI16DX3riDj5bmRaXOm6c -BWXXbzbobeS81VXBD0VldSUZLGMplQOIQ0UHOGLWH3QEWh7PdUsm4NBnAEV7kW/Tx3AVnrK9gr8+z+wK3lSqFBUPzHXDx8DiqAEunUNUVrirdWmdXBXmFik01WE1KyVV01WMGXRJWB5Xp1UqyXsgBkIbvmLcRVpiXDxAriCk6yvNWS5X3JVGkXTKHZKXUI7iCV14yza4GM5VtkqSrj+52wVhzk0+6UFGSGnYRFFCkMd46SH7d7JtVxp4RbnBaEv3 +rjxDkjtVXm7OnkXOXRyWDNnElZR7H7brhIoUVzQgX3dWFsCAbxCC7K8D4NJziwvdWBxUivZzWwCIBuxg3Mit2m6CRPIyYEjKUAqhpByp01VENX4dVD1WYVXgZUY2WVW6VdXL8nVdU/PJr0QeL7GTIZY5NvS6dLDbKIWQjtXbJgX2ITOG4nHCLZCFZgl5iaU9Y5QzH+2Wy5VdXba27fdXeA5cvhkyTBBS1uxH4hpcB3sA2k7OmBwa6P8lF7lStUM1 -me1HY94lioUVVJLkLzmVDm457tdWo5KZjnU1Hwg5RuXtlXm5WuKXEQBjdWuYibmhIoCOeCrEYfpBoTZZCzxTQxECvMjsMUSglrSUrdXQVWmdXhZDUdUS9lZdXs9Qg5XyKXOsU53ZK1p+fgvNUnHmldWsdB2W6reEedXQGL/mVd8WvP4XQXDNE1Q4G8mj269YXHRl0wWt9Z1iRppVFLFfbHGzLzFWfqkbhm6zx+hqOkWo1VodV96U6DAqLZ3LIngW +WlTgaVmmNXeSHfohbNVQ1XVNV7VXbiWUiLn5zA3Jt1lv2Zel7aBRIsQ49V6GbiOUCjJombDTbYpGjpZGN6L4oPSYfOXXyFXRlBXbeNX/LmpxnyLx8fkS+LLZ4EpEmRUyQGCWXmaUuxGB+U7aX6zH8yVN1Wq3luTKSeRggD+NBQkgJl5XwgmWqSTDeADvxBByoQNmNtWrdXNtVIFUtlVxSX2L4dtWmqWJtX7VUovllAHMWBCARu5XWVBPGTLuXAjn -M5Bksy78rO2qkyBn1STcwvgBglAh3n+gwQeV+VUUdWmdVTOSmtWDVX5wFnLkM1VjVV5dUTVVmIWBJUzukiRasYT1eUR8gIYQ9NVqyR9NW76QESnE9UnIr9+lStXWlWGBUgEXqA7FtUiyxZhAYjIvwh3whOgxx4YY8wrLwW5R3GUcvGgwXJdWDpgv1X9BgF9Ww9WclWb4VLKWt5VNNVtFXm9UCNlUMrA7CZiWV8m6dKQ9j8RAHrnIBU2qVGBjlPZc ++qrNpFlxWkpkxdG+BnfMqVKXbbqpWHlKU/3q+NXxOVzmGRGU/VH7UFVFrPXaBJUKpWrRE9TivtCmijKEgCZzPOz0ORAmQzQw2rArWwVFmYNErdVGNWNlWosDYtV0bGeZkrrabpVKVXZFUqVV4VZaEKZJLfLjAhR3VHOm70TG2yjZtXNnqGPkBfCvkB4lXaKVfAHdt5MmlyQYwnrPjEZhVfzYLxnf+XaH5euDP9Ai/yIWBP3AXuLrODSAB/ghWsyN -yqxozm5ERQ4yewFQ5zYWS9Xo1Xg+XcFkp8U8UTwIC78p4ixaEK5NHmIRrERsdzeuCKQqKv59GUXtV/ag2NWk9jz9UZdXzAX2L6VoVcNnctWg5VbeXZoJdtLgK5NqiwOU7KXedEXm5MnCXdVdEk2v7U9WVz64uGtXkFBmDiUKalAZEtSEV6kpMzE3nCEzjsWyCkebFBuGBqWInlglk6DAj6THTnJAKZEBNtxgHxp2COiL3ULucyP3C7sY/9VMlWMt +9Work+9Wt9WrNXt9XM1VmNVHzFsFl21UEpV3XmqVU2pXUCgtXBU6DbJXWCbDhVXpgQP6ENnIISBRYNpV/vm6RWUIo3NVGRVfwHMVUHuWwlFqflJfYIwk0PqqABrLSiqA0IDvIoARQ0gxMRCXyR1tWJSlWsWc9V9FWDYVlNX1Qmb6JUNW2NWlpVjLn8nBguwPznbeZlHhZ6UjtVGImF8UGM7q2m4Q69dVFg4h1W5ukiOloMVCKbErzTxkbA7sDUff -WU1WtgUw9XADU9HbbdUjECXNVRlXPmUV1KA+jgZTVqJSeXDtVxGal+CPLooDUMUEk+5Run6QUcBlixGeG5g0aPxyTYYCpUElWUMUx0BOVmipWSnyuryI6DhNxq4Aa+DuzzP3ADGySXSy4Vyck5eUx1Uz9VXtU+GXzlXv1Wur6LS7vVXmCVb0XxZadIY6f7xPpFJAR5VAmrk2jftWD5UBNVgBb/tWNEr/al9Qq+tUQl5HPwRDWq1U5BwMBl+t6xDX +FDyEtsySaKIEK3yRcvhifAXLjlniN9Vannn9UYtW8ORp1UHlXEdVcwY/5EJtU2NV7NUr0X1LQaHBqnAeCVOljPaJx9Xo1XJ3CCAWMGVXnoNwVhi76RW2SXghX8rF8Gm6fnTWGPUGC7GByWnBmcJJRr6k0UGDV89ZvuXdJVhoVCqAF9Rb7Z21nRn5fgRVcQBaAEjneWxpiXXtUrNX05VKsRg5WGqVfyk1rEnlVVNUUdXFpVT1VwZXU05iSw+zledG -/qmPRkjHnLcncwCflXAKVHgAqhoyGDdpCvnQgNB6xURZjVBVWDVWNVcDWz9UFeX6IWuaVDkXPPJsNV9/mPixy655mVKcXf/aGRJyOC4Yh4VX49XvNVd8T3ildSWutE/BxylGspVXA5l9lvKWu9UeWmzBUb+mewE8B5qlHscniBnjDWjiWNA77pXfRV5yQ2Cgj05RADjzxqfiD8n3GAE1DRAB7slGdUv2QmdV4tRNIA1NXzwW7H5WdU5tEIeX2eVt +ndzg/EmwRBZUXVUjlW+lEuzqMGWjPmapnDEUkLoxEFb/56vkypV0b7dNnSek99Bmu7/P50Nm8dWD7Gmtk+7GkEX4pko2H+BmshEJnksASBxCi6pEioDbZCgA7vTFyLTIADZg+DUQ9V4dVFdUBDUjwW89UhDVd9Ugimu/nwlWUdV7NWyZUyyTQyjT+pc4WC7DZWWKBUBfCuaGAdXxzEmhHglH+dW4uFIj7wZlMrpGp4yHKOWZccqKmiH2T3Dp18Dh -5Xl9VVYVMXiaTJgmpwBUE3p+CypgikpU/tX/OBelqn+VuEEfAEqGUSJ4wrmGVWrtVcBXqA5McWjXjq4g5rCvIovaTR1AxgaIADaVCYUA2hrYwkFpQUkDGdX/9WmdWEZEG9WGrZrMqVDUV9XfkWFVqFtmeuY5ZFCCzZJA7uWXdXEVYJ2VbBGaT4j25mtmIQXNdW+BmbhkmLE0DGiulpT4Se4ArnhApDsmgzHeekCe5KAX5u6/0FYNWbQY8WmtiUV8 +5xyzodlqFCXEjq/rCotUY5hNtWrNUwNk4DV4SV7DYjgD4tXKVUO1UDUI+IDk3AGKjNjmSpFKubA/T4La6tXT9WlFCT1CDIUc6WJQUvKUAXLUXlaXqQjVq5Wb9WqrFNTgzs5dubaFB6pJ9wwtvBRMinKIBOXeWyrEUv1WrVWDDWDFXcmGoakvDV99VvDVEtU/MVQdEHXjSlVNNXV/gvfB0dWVVWVglkX5lWn97E976wsX0DW21HA5ysKoQMFYBFWc -yMKXhjAJxVMlgtpI+yY+ya5uKCGSgkgTRhPGCPXBa+R1gUs/TySB5qCRTjC8iUdW8uXpdWODXwkX+XqWtUBHk+YXHVjcpiVs5V4TXDXVOkpnLi7bEGIO9XBgwiRVvPnGQZVNqFCFKGXiRle5pJFE2cWDI7XRU11oOb5OoxgB4XAU3UF86qEsYTt7nOEG6bI56GhGs9UgN6BUW3+VLsVfT7tt4abnRAAJdAvwAbKyZbINsJjTBvABXwCVp7wVl9Vm +bk6Wp5JyxXPpXbKJdsz9grwABk4bEfRNzhELBCGTR8T4spj0WiDU3DW+9UEdW4cVYVWveFELkKVUBJnGdXUhWmdU51V22U93T+4i5qXQbnAqhIsTqKW0jWRshbqUlfm8TblZ73Jmmh7A4WNILhiSAc5o9FcJUK8UEwwodgn1R6pIegyYiz5uLeZBZrBV6BpLaNWWJSlYjWQ9X9DUF5XD1UbdUbn7q6msfTDSWSEU7NUTDWqVWesVP6CQ9gWpIUrk -HNW69U7DU6kGttWbdUdaXAoji2UtFX4pWrKX5qW0gCaTKk6hVxVRpnAqgOQD/5iXdXszEKDWq8mH44n9niByXhz+KyXhyqDI6STQLZV1bkcXTnx5BWMcWhdVphC9gruZDvhhfwqDfyI3bBHyBCaURCrmgdkXVekHNUQ9WJjWd1VfICMNV0yEujwl9WNNWhEVr9VLvZXpWClWfcjGGYjOVl5xlILG4UO9W7qWwzmZmkpr7YvLRrHyvk9Fy6zwKNVi +1R50HDpfDJDXMdV6tUBfCIVzsdXeqXM6V4Wx0GEcnx+ba4E5kvlTtUvZGpp7zpmkFGrFUKjmGGW0ia2VqIlGUKGC7mkKG1jWckUKGmbUDmxZbezlyIcODZ8C5lTHXDRxD2FzzVUs/T5bBLVV+jVc9WJkAj1UzSkFFbQwJw+VdhWw5XnlU53YhADn5w6DlktVJBaaULBM4SlWGjWYlXy9WMpXdTxUWFnOEhR6EwVnvZQXaPTke+XNVlynrpkWA4Ud -sTudkRux0VX65z6dnGNQKKmPY7wTkydWbHapOFOA4a8mNFyJGk+tHyZlvjXYNUFtU1jm8px21XWCDM9lqfg+ACiUB9AXrFyI3b3bTcGSmJCXpmbYgk1h47RxOAADXUGUODVMNVbdXmY7c5U35UuNW9tVVDUQ5X9UrAFQEPkehWGGLcdSEn4O9V1PiHyWGoanyXFwU3V7pWHnBmkdzNXm+1XW8XU/yVSGOv6gskymXu+zKgQv/kvXS7UAXeJCOCd8 +yG9tkrPmGOICuX3N6f5aGel4JZR6GFhGDiVmlUk3JxnaoEpXPDKVA3nTieR/hTYICaJBXGorWzTvnN9WGNXiDUOZXDjVttWqbr4DV7NUnsW/XhRHDfrDv9Vw/ngKqyrzVGI/9UHkI1cGB5nIRG02XV+WSUWedWpZKWwr5lq3OKQmII6CCxLONBXWj8FwDFjLEVb5B0mD9jV9DWDjW3/EPDXNekhjUuMVzBnhjXWNVTjVLvYWswjOw/ViDhXno4gr -xPtBZhBUgAF5ybFyP8kk6I2PEGiWwjU7DWD1wIjWFuWsqHUUX0dVIeX5dXnDUC5U91TwKLnWRxVVMhai/7NDWqFUE9V8nB4Ho2JUHVrmqbAekjGn/zJoRZk/aWoyy+mygVk/YbWERUp4FGy9am1736VQwJllWtOZZVViamcwVLmXPKUQSUR+U2EWH1UZNVkA4QkgC3SFRiBxBjsi3XCimLwWChaA5tTSZo91nQTW8lBqUHs9T69VugUWdVBYEb+W +TeUKARWfxWpDWjfGGtW8rHPcWqDbgjniQL69lXSmazFSHaAJnrpmvX7EhERsExdWDMG2JVfjGi7mwe4edV46ZPNYcNmoKrQJVsGXB7IXiogNDegAInYURDuTIw1L+8aceWgQDeWw4dUFdW9FVulVo2Ww9WvrHAImEjVVOXMAV7NXqcVDaCYghu8xmuUzZ6RTHLjX2dVH9G9MEJCVLjb9TGW9XjkHW9U7rF1fpxyVhTUdiW8jXDVWwQWYdhCTxRgA -PtXoTUV9Uh5U7QF6sTjTnkGbOm7vCCD1AN9Vw5RN9Vv+irVXaTWmwX/SJYsUl/mqdWbqDVUyyUCAi5VDykOqKQpMSA4fS5BDK6JKqUAUkftnhTVyjVQ9WLqWlDVJUEq0WRlVfGVQDUDUJbmjhWbN8BthXsdXv4I1wiS7C81XoIT7xVuEHL+yTjb7mqMcHTk4Y9mKZXETpoRHoemejVPEXpzEyZWVhGLWEbKlLDq9cHPjWzTGI0VTGC8jV39BFyTw +RIzM0LXIgwxChdDx8DPMgrWxYmViDXRqgOZUd9XW5UC0HGxWMTVC9Wh9Ui9UXAXidhHGSogaKZVeigdcBl2i0jXMIDtdWolicDWz7KSbnyOUsDml9Xkkr1CSrJzOezv8i8lghiBxkSZ9zhlBV8qJ1UYynfOiWTXENXFdX+9VldW/ioxaoKJXbNVMTW7NWqVVbcW1cTCcIMMSZRXHgiLVkjtUUXmIbmMoUjAWQlEX6HOGHReWqLatJVFhElCkjCV7 -1xAvqDlZyayREpcTKpJi6dFKJWg2kafmQVXt1WVNU8MBKHFTjXDynE7n73rX5UOuXruV2dWoqXtoDMUoI4nVGKndUK/CHyH9HjjTW+lGCtHYuFujFY1k4QXkVwsbks9XW8XkG54DWUub4lU9eW2OW6DWxsCzBmlTUuiFp8B/aztXTs9CPjr9apw6EFwT/ax88WZw7c8DQjVbDUiTUTjUKjUITWZ7lvrGfTWp1XI9WVeW/TXb2XzRmnGwObCB/n5D +pZHTULkVbmFqqHi5perSFDyAkBPsBV3yZgLYBA6CQ3CrpTW9DWFdWDjVYpWpFU4pVxSXf8lgTWqVWNZWHDARWKdZBPMlLfCkh7rTUAeFBsW5zpTHkCrbMpVYLrs6UE5GkXwXyKS8Vqha29UiMUA/DX+yZ4AFWaHUDwbB6KQ1HTSgDqhorWyAZXYjW3tWkyXg5UY2VZEq/TUD9UI5XmxHcZja7z5xUMJgeRg8TXDlX9GWIlbIZ5vlV3nmBtr6eXaH -gMWSVdW9NXVdUWeTaEU/5U20QXtYSrE2yZ2+g7gUsHGMqVPKUyaGTmVHgV43nKdFbjrLd7wzWFcbBdXInlxeWjXhucrqCoyeS2WhbZRcvg3tzwAD/RCkzXs8k6kEPTUVNXHNU8DWKjWITVpjUwi4MzXvkXCeW0+V4VYZkRwOQHljDWEdrHtNDHYhtgT+NW61n5aRtknaQXvanbBW3C5LtaGcXk4GqMHDVEb1WvMaU3lk3kXlUAyFzR4bBUDLl3Sl +6kwx5nSfJDvwiA/C/fxARTr9KX+JeSQLdXqoAS0AUTVvTV9FXTKXX9UtOyJC4OTWEuVOTWqVW72U4IUm6Bl8DANVQqJn5A8XAjtXxvAEBWMDWyHZHyRf+VYRXbKKJ2BhiCYdjeZBzJLw1znADKeTSTDnyALNVupkEdmadX+DUF5Vk24yzXDDVRrnVCxhjXjuV1ZVZJXUNUT8XTvHaECxlholUzaB6HAJAineWaDVZiIisXhsWNTFLxWt9aQLZTKm -5KWNxE/CUqZms9UJrGfSH4uVFpo8kXIhXLMVS+XDdXCJWfEV1VUhVpQ6EWADveY8GRV0hz+Si3RRSLN1Uxtm3W5CTX+VUADVtMUdTURJXcLmqjUhQXqjVCdjkswilaq4ByuQSFE4MxvrBqTVVdVyuX5aRwxLQ94a0FaXLktYmAXIuW1iTmDGv7L0MyqDKzzVfDW9eWzBltjXiqU8URE1AcHR7oguZDAZClEhsULwbBuzzo1AJdUHnBXOAyjVk9yD +rhgr9UfLaLNnRB6v9DDq4VDAW5SEgCHLTFyKCxIKS5PRz0Yne9UyjUX9X05Wg5U0TU/oX6nwI9UYalI9XX3L+dzyEWQUlyBQxsJhda3PK/Kzo5Va4Tr1UeVEiTVKKDaGVuVVAnnR5nxuHv2FMVXGFVuzoCBnCY6ARq0pltCZmhn9rSyFahyXDrSJfaEwL1jbbAb2HHGzI3Byv/FgVWCCkjdVez4e/hLAAtWBDCbhNz5dYb8QQlCoTTkEndFUDjV9 -fA2NVKNziTWOlEFn5CDU9TVOhUDBI16DX3riDgIHkIDXJKWcriRjnjTVr3kz1UIsWLHq4cXKnmT0HhIoUVxmYGtVGwu6XuxCC7K8D4NJziyFsBgJUahULYX0Hkd7mYdVBZjPOhBZwdTj6zCe8a6CRPIyYEjKUAqhpByq/9UwjVBlW8ORssAJ1VttUIUIEVEp1W2zU0+Vm9WLjWgsVINQmMjCMi5RkjKGCJTjTXbJgX2ITOG4nHCLZCFbSsVgl5kb +FXrdVkNUB9U9vEoX6UhWqjVc1VzqW2NVsCVYTl30K72hfclhjygHg4zST9WIwapjWowUhaYZDVe35Yo4KlVa/kTJbX0V78HIaGs7zHjUvroaT6zmHdUVUNGk0HELHQLUE56WLEJznhoH3NUnRm+jEi0Wjv7oLUR8otG4BhCTiEf7QNnzhHIFaW/uRdbH1Wxy6GtOAZJEpHBDVVDiV+GKFQDVvDqgCqmWs9BeSRlcDNVjkABoJLeZquOWYDX/TR/X -m8pW4xl3SFZmkIKnL5WdKU8BVTGBICU0MWqvnSjrBBS1uxH4hpcB3sA2k7OmBwa5vMUCQV/9V4LWlTiD1m0zUvkU/pItzXeYXIkVZSSUiLn5zA3KkX6uzWSkK8HTn4WezUg9n+qp6GYoOWSJpombDTbYpHMBWOelNWlvDWrBVVulXRlBXZmjXq/mpxnyLx0AUS+LLZ4EpEVJUyQG8YXItUuxERxWW0XBLVc9X+mVvlVARVUwCSrFbtW+xC4IwoIA +BBDVpFWRd4hjUC9W5VVEJU+zW2NXs5XfWAmsH4AmE1EAajTMUAjXHQVZTG1viCRk5kVg06jqnALXHJrKLWqg5UFVT47DeUoNV+GKMAC1vBnDy5Kzz3hbADc5JNszx8QUQnOtkh9lk4W2ZUp1VF1T7IBgZWkzWpaLDpL51IUzXTjVO5WEEBg5hSHgxhmGRJZDjPODo5VLrk35Ub5F8RWRs4Pe5k+6nvkP34yoFgW4RQ7EgpLg6RzShQ7RLURQ5aTW -wkh/1CgxB3xBtwwS07eADvxBByr5NktTWnzVtTV7DXeAVMgX2L7dTULWVuDUOzWusXYYGH5g42Sj1V824OWIUoXjtUWJX+qrNpGCzWGwynFabN4giUf6XN0Wc9W8qWIYXKmHwqEJtUgdWMcEPoxdfl2HFeVrYcUSIWhRU55W4uVm2CoUWrzU9TivtCmijKEgCZzPOz0ORAmQzQxhGXeWw7FmYNEnzWwTWmdWP1VADVKjXrC758kOsUKVUb2U+MWL +LHkHlKmzDGJBGNKI3aJdCnc5M9DvNC/9i0pxsLWvTVWTXWLVssDcLVfTWoiT+1nQfxyDXMTUH86FDzgK5awTo9UggRznKS4Fio4+LUIsL9T7ZNJl6kInRBe7+aHjpE7FVCXlQS6hBU//SFDUXSnM+7j+niFZipXY5WDvQLu7w2FjiEuflkFHjmnWLH06UGHm8aVjxnrb5rRUlg4TkVDDndigDg49NzxQ7mzQpulA9CP379OlFvYgDWR0x+NXhg6v -jV0/mXwY7ZbAhR3VHOm70TG2yjZTWMExN9V1UDPDVphEpHbs3YraV2VVVPbI4EwnrPjEnFXQLX0cX6GVUwB2VUHNleuDP9Ai/yIWBP3AXuLrODSAB/ghWswrWzrLVZLVbLU7DU7LW8DV7LXYpUd/Y9OU3zWIaV3zUblUCTQtXBU6DClXHXm8sUapi96B3LX7hwPLUqDCA0UYOVNrYNNoHjV5ZV3dVGTp8GmwlEAGVJfZCoVvQXtjW/6LRAA4jKiq +IWiVEL9khVU6zn+vrEqzhDiqAAsHRKgAvgBfgBRIw6IT7RETnESzV5LV4tQU6DjTWj1Usnno9zyzVClWKzUD9UpuUa9TiwYN3m6jVCAbU5pUHCNLWDp5J9U/dGcrm29mVJl4DZyNWrk41YXi9Z7YUb9VGzV+GLPjzLLo8gBhSCL+hL+guAB+pAifCWYzLTkcvFKoVEzUfLX85BBjWe4EzBlhDUzTWFTXyDWqVXYFV0dDCDa/tSIxkUKLJnH+WSIT -A0IDvIoARQ0gxMRCXySNTUYym6CU59XbDWd1WKkUpjWpaKty7XzVFLXqiXm9XoVVZ1XIMQZY6lRUtSW1XGc0GmLXa9nIIQRmCK0H3e5nSm6YWTzXI27zHxgDwiOnfcUt6XyozjxnKbzmrVWBVo1UwLWPSAgFWk5U8UTVEgl6ItsySaKIEK3yRcvhifAXLjlniwrVGNnwrWRTX4LX2DVmtVHblVZnzxE2dX/FVRpW/TUqVWASQaHBqnA5yVOljPaI +VJY7upWzcqGxkRxoKLU4ilKLUbJEX6o3pVnQFdiF1VWdJlSflVJnTNm86HEYUIoGV+U7qED9nHRmEKFskU0TlxSEug5vZHFtXIUr3OiOzxl3wPficOSFNQ8UIyXQvsDjJVb5CxG4iFUZpX55UBYUtRiFLUQ5UhYUVjlgM4VzWMOkkHmn0JnwAFXaW0h4kjs8WGOBaNTJjVT9UyLVjaB2kkQ+GqTWZNJ8NWvaVMBmbxaplWtQo1Q7LXI1Q60YrfjF -J9IPDXIISRb6NLW4+ZpfqXE6lzLDhVY7o7MUOq72yY4OXTWGPUGC7EbTHgulMVpRr6AcVyNlEXY8h4bhVvQUklU8URekDWtwF9Rb7av1nRn5fgRVcQBaBETlrLXo4UJjV0NXMtVBVkSrVfyk1rHL9W5dVZjXNNUV9VRVVCuFiSytLledGH0XwXF2mW1LWCNW+lHPPkFTUKFFVlVUbb2EVBhUQVHI3I01E12mtlXO1WpEXImXABHGpnhpF+LW5MUJ +mc5fj4QuU3rkSAClDCWWhKEi3vZoLwYCxBiCpcAmixE8510lhthvLWjTVCEU+oC2LXBDUHjk4oXbdUP9WqcXTjWTSV0vAYox1FgmVa8EDEIkfzU0GYsdVjaBjbB1TVD8KjqkZuYaTXT2bUxmW9m2SIDrWczWHGYKqC3Pxt8ysABeNAa4jPbSyEo/gTt6jYWkcvFXtXLNVWrW89QlrW2rVw9UMUXEQVEjW7dWSBI5gDVeVd7iq7oVTV25gQoi+rWf -mFUjW4MUnrUhcXBwH+BmshFCoU6DDfdWzzIsASBxCi6pEioDbZCgA7vTFyLTIADZhrLU4LWUzXKLX3YCqLWBrV0bGeZkBCnkflXNXe/nv3jCLhuj4ThgplXkmnaGEetB5TEedU4eUQzXxzEmhHglG217RzVP851dLwKnq/KjiWCkWeTXFuyOWZccqKmiH2T3Dp18Dh5xyzodlrZbmYZq/rBQTUY5itTU7DXFNl9rWFPk7SSkUEm9V2zUULUH84+I +zWAjWJmA6jVgRWgZnaYF4E70gYPAYtTjeXxW4DGgBGOzFcA3qF2tCouWiSBlZWWLW7lWcLUjoWuzWd9XuzVY6lOrXzlmr3n0ZhWXJYT7dHJuFmkyKOaGQZD/MWVVU2wRz9VNmbH9l+t4kxmQrFTa5gcZnRmzkoazkXLVQSXJcDPXRlk73fiz6LobCX1iregfgSIELBdBwAnkAXkrXFrXRTxUrVipmHjntpkTjXOjnC9UFVWXlXLGJqTn4FXZ7ySv -Dk3AGKhpTX5tk23TSXGWUA8zWN9V8zXV7BuRXKkk3cVbIVT5X4Z7UracJUybUJDUvDkdlUoYUrzXaeZNTgzs5dubaFB6pJ9wwtvBRMinKKqBXeWwR0VKLXGtWADXIrWWzX3m4jgBsbXkLVrlXm9XX8VQdEHXjN0SzoUdcA0XICzVLVUaTWVgmDNVfoH+ZW5GbXnkZpkZvb6rVSxGFSHsD6p5KKTlWcZZFU80Ubvl4+DozXMQWzzImzBFjTw1ynjZ +H8kCMzUpDXMzVQ5THMR0cnS0XGvTE/ajGl525E0VzN56YUmCH+4aGp7SbUl9UhFV5UbrUa+KDUjyekDAth8Tms8yspCf0zM+VP3GwpAjTVQ9U7IW6mXATWm0XelWdhUw5VMbVFTVvkX4ZAjGa+DC1sWQBbv546LkNeVwbWBW4wNXxlVf7awaqhU49AXrh6gzFJ5YziEfJX4nGJyXTqlA06N1UplV5MUyrUlun45FjjUXSZR3njFk7+k8NnscmUtl -NzhELBCGTR8T4sp8cU+rV0bXZLU7DVyiVwVXstWi2XXTZONWZjVp1XMzWo9X0+U1UBCQr/sAhDm3spIsS16WIbWRshV97gpa8TblZ73Jmmh7JkWNILhiSAc5o9GhbVBqXG5lY5AiLUOEWCuJz4b6+EegyYiz5uLeZBZrBV6BpLameWJSkGbW4LXGtVlkDmdX7DUUZH0pp8hVKJmZmUI2V24wFrjcbXMVjdvFy2m88zV3DpfD9zW8zWDzUg7B9ng5 +1FzTqr5bTTmoO1FZmnKjQC7kzalpGbySp7hWrjaDL7VjXQQVJdVt94a0payFhfROrBhEoyUD3ySY8K96iU46+9qPMVfrWD1X6bWQ0WfTV2rX7H7g1XxtX9xXf6WP9V4VZGOxZwICRHliXt1m/1JzhjPSpwbVu6JO4U5tl7RnfNm7tVLUDsSCf8jbqBgAK09DFvhsXg4agqGC7UDejVNhnJ1XfrXWLUlzVNbWQlUyDmDsJlLVzTVdbVz2kIYpqvCk -JWLUWXKV4Wx0GEcnx+bagWUxxW9AH0pmfIUJMUQukYnFNaotFpHV5/zF/bHQcXP6aTWGPj6jLU39U2rW3QEhiQatkxLW2nKXuJbezlyIcODZ8C5lTHXDRxD2FyZ9WyfD5bAGtUzbV2DW5LW3tWFHFmeENEX+2UQDWm9VWbWLjWFCXfWC2QgKuCPLmwp6dcDPWx49XqTWtDUGEhPLVIknvt6dm7ZlWzmW9mpIuXQcawUWwcUiTllIWY557eHbqG+d +bAVTX36T/HonrWtrVfzWJjV1gVqeWljrIAzDG4t+n+0ln66sGUJLWd4W/AB/9i+KALFwFhCLXgtWAXipuxjeDUvoW1bUA1UbbUUrWdyW2TV3kFtlXTqVmmV5VXqjXuznX1gGTw96BysSaJV1B48qiAyVcrXm3YM6Fkd6z9mONlfhpttmWd4uVWTc77Vb7LmobW3A4o8kJtnl04tVUPVWEByKQI/7FTa73q79w4AvQI66DWxElUx7karXrzVlV4bo -mkMU76a/bHgCXZHnecViNUewHI3IzBUcBX32VcBUM9njHk3ChxnaoEpXPDKVA3nTieR/hTYICaJBXGorWzi1kbLUwTV+rWPVXzbV5LVRKFBmk8SWAsX7dV7CVCTyCir31T4rUKP6bBkobZiITjTWpaAQNUBhUbeK3MrfMqkpk1tm3rVI0XA7XmvL5lq3OKQmII6CCxLONBXWj8FwDFhh0Vb5B0mCI7W/rWzbWw6UbdW3vn8lqaLW8lVxJWuGAWsw +DR1AKAgCPk/gRYWBItSugBq+B2zUHGlG3kD1Vm5UrrV2sXnzUTTXfmWhYUtWFDRXZUWvBXyFXlAzscxAKlibiI1VhmE6IKmHh1OxcrVlrALMXuC4hg7weH1NmFd6RFmB0Vl27Z8wsrmTWFYbVka6/+4gBES6Fhjll+6eNnU9WpNF3tBeuAN+aq9y5niOzyxfRTIQtJ7rsR7sniVWWrWpVVt8D8nE5TUUZGl5WxhxOLVLvaSxIzumc7CIZWlVW0Ew -jOw/VjfpXrJjPZzAKoPuHjTVgOmGy6pGXvmmqDamWFHBlApVtWknZXZ55Q56/wFil7EhERsHpzXaFV0HFMpUHrVGhmzfboRlvCUbeH+jUA8XrIWwCC2FVkooEQAY3wRgCFwSLghYgIrD53IaVBigQDeWzkzW1zW59VJjVLeVstVELULKVapj5bUUCVl9XM1V8NlVgCkFaYghu8zcRX0PK/WTysTp7V2tG73lRfY+cGpAWXRUSWWkjEz5Wq56/6WP +wrLLY4+LWzM58bw/znJh5ZLmNTkMoXPOWb1Bor7LBXmPlhAW5DmOln6IWOlkuiXbAb25zlVmvs4ODVsFWHGb5jzCgAL0Q0RRUtxxDiCMw8vlS4w5+kj4XqgVr5WcLWytVS7XfLXMbL4XLf1XDRW/1UurUHxLUczUCYhyizFUf9UZyre3D7yg8bUpjVnrWh7o8rUpTZlPkuRTV9lMLlxeUK5nZemKQJymXyxUk3IV6D10j3sCQISCOAHIhJ2DfpC7 -won7WaDWozXCJV4+AP9VMljaQygpIRlCuCjQ/BqCS7ehPxCqIJz0bjAUYyktOW+rXRqiPVWvTXQLlZzaTEXwaWhBXAkmSBJKoA4X7DCg6iWINm7KXV2AdUWIbXMIC27WqjnDJXKuUgBFrrWt7nWVXtA4oHVRbWxvkhiB+iAnyBHOCmWIPjp3sKcUyHa5BdArWzfOgj7WirX0NX6gIXzUlYXvTWyhEAHX8hVAHXtUk+2JpuIMmT1AjObXKrVQVLHg +cgqGBWZWIOHNWUg7X1bXWrVd7WldU97UJNnj1UPm77bWRjVdbVvOkjxYu3x/qQSFF/RiB2yXbUGGa5tV7JRJqmVJUNxJbhkRQ7jeluOnh5VmTnk1ncGlBoWQHUc/aSUBAZAodjVDzpfKOFzNACKJwWzCmzBAEU3DlLrWB7VkMCxuClzXtBXZSl/LWzYU5FVdbVpNkNwbUxjSYW2qUv5rY3SzGRJ7UXrUwrWgDXGFXLtX76lmQVSpogpUOHG+zI7l -gT1AHbXCbVHbU6ohO9XKSF7rVXQVirbnyVEJECZF3xxMkUY1Z9s78pUl+q5iT+aFlZ6jiUZWARiSZdlerSFDyAkBPsBV3yZgLYBA6CQ3CqkHU/rXCTV/rXMSVMbVcSW1UX0mWhrVoTU/TWo9Ws1XD/QRWKdZAeuVJVzbbWJrUeRiTTVphE0goxEEwGmTemJ8H9HFHBWVC4TJZqSVVWnybWWFUjHlM+AFzW5vLX+yZ4AFWaHUDwbB6KQ1HTSgDqho +4Xooi9F2jXmKUydXoMCUjwWITaihUrysDRQPm/JBukAx9FCxnRVmOzXLrUVKB4HXbbVMemtbUcIAR7UH84L5wMdl2FCc6b4IVGPE01Ri4A+LX+OGYzkSfYj9a3A4lhXGVWdm6fqm1DXbulk0Xo8nHNYZTlH+mR5WBVVoyGQZkdGHBVUUnEhjmMxFztVt5UcVU47XXLnW+Zcam/iX1cXDQx+oUWh4NPnViFxFHbmE9Kke3Y9TlmTmK5VzVDH1ZjzV -rWy+VWGbUADVR3kR7XnNXg0DIjXnDWZ1WUJAYmSulkv5Vvwm4JjcZUDzWubWPGTsUHG4aBtpuTW6aX4sBsrXdgZJ+xPhiZviEqysTnYgDj8b4IC3K6Vcop8QL4VJHWmdVDIW7LWITWJC4WbWrlW8tXm9UV+U9mAm6Bl8A6jXWdVwgUMRQczWIbXxvDDBWGrXaiFk2WodXDHl96Xu4WMcXwLWdgrHAAx8Da+IXxoVvB+/g3Zwf9CoWAcJr0YmGvld +dFyJenTMkgBExHUYvTy264sVRGXwgV+mWpqGaLWHRUHlIz+iNgDQOhWswj06U5CaokcKhtWCV0wLflyclGKK6bX+jU37UttWxtXPRV+2qKtVyFUEVXBmihyHOrH18HEGJx7UAcjCcBAgQz7V+rU6kUmS5/aI6DUKaX6amJFnkDHLhnq1V6GXvcWNYVrjYW7XkLU6GVTCX1jVskXPFXrrGs7XW7XbDmULWPjXbKLAjTmFJ9zYeeCNCGCAAj07sviT -rVPTXs9Rk249HUHBp2AGTVnrRXDrULjWcbXb+XTvHaECxljCtUkIB6HAJAhHRWH9UTtWV7D5TUC1X6tm2HRkjUo4b+ZUqPZRxqv9lfLUfLYpsUymWe0XEtW4bIXQaJdAFhBwgCriRgxBWvITRi+JbjwXOsmXUXq7URTXf7VG7GELWpjWiga4pVDrWFbWG7USOX+dxkvBH7CJKV/a5Xtr3ri/Ky81Va4RibX3cG57XiQI9FlaMEk1kexFv2HrAbc9 +YChtVHYCDua4dWSzWcLWEdVSDV6dUk3kqHUYC6VwSfDWkrG2mUd+LmvgVYnnJjo5X1bDITWmcXlvnpKXiyXqfkK/l1z4SLZz9ZNKSyjlaRV/5U5cp7wX0TVxOXRDp8tYU6VuUUzZVlUG3eVAgH3XoaXYedXn46cyCclhPPAw6BCTzCUAP+xA9IKAh05D92nLdUATVZTWMkIh7XjoV0MXP7WRDVxflvyRVfTLJ7oEVBzUdqggKB5SRfHXC2z3EU+J -XEqAG1XQe7XjXlLGEwLYemJlxmhn9rSyFaRtUOyXPY6kHTytXinVA+p/Y43Byv/Fdno2lXhLUovl/Zx//EV1UOgztsxH1RSnTPbThNz5dYb8QQlCoTTkEkprmdHWIrUNzX2NVE7nMsU2CxapXSTWUWWyTXuDVqyVJiXZHybjBMzHORCgHg4zQkrUn7xN9XAMjsCVRtXWYG+Kbiekj9Zk14/HZPNrIaGs7y87XymGCbZhPn0wVwUU4PYE56WLEi7X +71TUOZGhsXB2WOIaHuIfCiVwRzdRHwAxDiuqgZJheuDVRzkCo82nP1UnzXXHW4jWyVUZUVZSlNqmClXEHX99U53baCq8wqnghEXlRpl6jVeBivAGITVXhBylVevjlynmcXh3qrLU9OV5kVrOLEMHQnWTpZDOULXlHypGIiCMzoLBXgBsGS+tKZkEBirfTKslUxWkuTmZTU/rXg7V2LWGrblOWQ1UCLXezVvtVs/kZrjHmQd3Ib4B+/mMwgqrC/7U -hoGE9kGdmx56EcWjv4pnUR8otG4BhCTiEf7SEuW/uQ8qVEA4G24BhBy6GtOAZJEpHCR9XLHXm5WzFmUhVN64n+K8ljJ4KaCqs9BeSRlcDNVjkABoJJR1VkdWh7X/TR/XB4nVMel5QazjUr9XzjW2nUOzWD1WUNwmsH4AmE1EAagt8U6VVRAVcohzWCJHkxtUsVmjDkosbznU4j5cCaybVXaqvlXKnWKlW8py99VaIQ16DlUC91DzFxqjiApDF0jD +gRa5uX/OCBtBtzVu+kTZkw4UrxUZzJJzXrZ4Bm55zr9OX/KBuE7yowFnWmlX+WnKmb3tClyRrIW5lpRgBDfzEAbL3jI6ASLkxWk5Dh+DWyHVB7XRSV37XAikyhFOoDXzWMbX4fnmbVHsUYEgMYLtohYQhIZWNjR8qQGNmLDUA8rlbl3bXN7IibXOwgdEXGhnXN77ulTrHgaZbZJ2CGdDKhzkkqTrnV5MCpV5nWabnV0QBKHb1WwDpHCzBnoVPVXK -zxl3yk3ikOmFDVNtWdnW9rXZbWT7U8jlnLmFLWRpVKVWo9VAhWSaUUk7n+QcHU6LJZDjPOC81VM7nYxXS74ROl9HkRQ5k+76DE9YxHcXlQB7A7EgpLg6RzShQ4wXURQ4WFUqzmXOVu9ncFlt7VAH5W65GNKI3aJdCnc5M9DvNC/9i0pxR1X6HV1zVF1SPbCstU4iWbdVgHklHGQ+YZHXuDUcNX7EhyUTfwlBYVznKS4Fio6/nUIsL9T7ZNJl6kIn +QGNmQXuLlp4uk5mBLOTY97RhlC4EgirKrTkcLX5LVCeWttWLJUzBk5VUZJWCLVhnX0VlH+GbJX++j0JBztSQ1ZyrzWsTo5Vc25+LXhMF7TVvAX2x65va2cGuFWpJG7TWB4ZP0X7mV+zqoWEQZkqzHzGmvvmhMXr9USskALU3ZbymFGLHDrEqlXZYWLtUmOV2JUYXV9XnAEoerYBhpyOU+VHS9FS9HZ5FoxV59WPj6uWlfsEQjUF2lAz4kXVzxnzt -RBe7yHWcLYBNl9DWJtXRZWWjUXeUkQF0b6etW+dVTsmI3JR8VuIVagW4Nnw2FjiE/zVEnGoKpynW1FrhmY5Grrb4PuwjiTrb5SOm94gDg49NzxQ7mzQpulA9CP379OlFva0rW39Ej7H6oZnQ5jJURtULzVgpWjhKNGXtvbEqzhDiqAAsHRKgAvgBfgBRIw6IT7RETnEh7UGHUFYUU6Ao7XAim2BwZjWz7V3HWDnXm9XuNU1UDxDK7uWQsVnaG2bA +aWmkINWf8yBcG8XUt3bRB6Mob4Rzwpy4Rl0LphKD2NCvTQ7rSeLHxin5zmPnUfLUFjl/rXCP62dEJRWnlWzTUv7XqnUftUFG5Q7A/Ur9aVu0q4qrTsQgXVQcQtH4JBnUtY4eX2xLrRX2gapbVoYDxeHNeLeFXvSnC+mQkU0/aVNqsHHolxt+ndOX6GURMWh+WKHx5jWeXVZjUEqZtbEZhHlJlQOLXQV50VLML3mlOCFYNL/PSM6U5D48dUPFXq9U -1LVTnVH9U6GpgqlJD6E56PlkUDHHN4quFsjWfoFvdXi9Z2kXqhWCpW39XnXpgEUyIXl/lMuU8gBhSCL+hL+guAB+pAifCWYyM5XVclGnVI7XEXX85DUHVcLldKGDrUFbVMzUknW/TWtNV0dDCDa/tSIxkUKLJnH+WROHVJY4nlWzcrmiU08HPemjqlbJEbtYmVXBDFaSoKXUMEVmLHxnVpflrRKV5GlBk7qE0H501lxSEug46pn7XVlnWzfnm5Uo +g8WD5VQrHFHZMQEN2nfV4ozWQuXU14jFiSTDdLxp8BvKqtHAqGBoWDhRk+DWUbWynX5LXynUZ1VKxLzopF2VwlWTjUHbXqnXUdXUCi/bBQTXJqzUHkLuzVTVX5VcBjaFXqeVfoHd8aj5WJxl9XXCkYDVUteUjrG7wUidWF/4mEX+HWHLUMbZ5eE/OWOxER2GqJbNrrEvlmXpcjXkJF3DSrl4WcbQsWeimcKbDXygLWtorgLXMxkLpFRdXVrYHjoA -RJA7U4RVhMivXT2WjGRzx6acOSFNQ8UIyXQvsD0lXR+nejkmzWQ9V4tQtRjdnXb5yHDWOWWqynU+UDHW9TVhyJnwAFXaW0h4kj7RWGOBaNQ8HU5TV8zVwYQTXUytS5iHkkVxg4AvQI64ZWGW/5OTHTOnWWUAu60YrfjFmc5fj5N7Ur5X/s4jgwzDWjXilDCWWhKEi3vZoLwYCxBiCpcAmixE8510lhti+XVEXXvXUCOW3nXkXVnLnSrVPnWb2UV9 +MX12nbnL8dlEEU4qlxW5JoqxjSm65yvSgVCmoy4CK7W72jG2q6EMEqkYczVQcXGZmCKrYBZAqVdzK12ksDVF2kA3XOjE0BJrUAW4DP0k6jgcJqBTwsILzTDnqCspBj0WfrnYHUbEWUiyUnWaMW0RVpqWD7UgbXWShrQxWVxnjhWoXr4UIQ6y17Zb4gXWjeRubEhDpJT6/KVS+FqZk+0X0TWztXCpWysXsN52b47lJ92FcVHDznSuni+neDH+yTVN -UvtU01QCpbsHUXSXJKVPsT29XqrWMDljaBjbDwHXyHoSDmCY4OTXfjW/Lqe6lO4UNrmD2WWg44ZU8UQKqC3Pxt8ysABeNAa4jPbSyEo/gTt6jonUgbn3TU69XdrW89Q+oCkXUjGW91XaoUuDUryVB2Xm9XMdX54imJiddmQHWIDWFmIj1XC3XzTmi3UyOVDdkmNB4E5owIgEWH1VYzWAVoPAYtTjeXxW4DGgBGOzFcA3qF2tDPBWMzz9Bh3VUpdW +LtIq8xApz5hiALTD9FiswJAEwG573LiKmgjE4PnDzIRqyxOxWUOmUHDJpizHTtf7QzLzapAbVJ9nlmXbEgFNSepICkASCiC1W69RWygkhpP6jHkBoPHiBjHmgMGVAHUDv6+WWm3UJEUySk78VUEUU3U2f6vFXLyZ23XLXlo+FiQCg+A0YF3FBMlisII64joupXgCcOTRIzELBpJjIBqU5C/VUFMGSlwN6RQ3Ca5gnsScHDfFq1Hgq5jUCyle4sea -dnWXUWXHX9rXAbXoFXHDVI9WnDXz7VVDUOdW3vLdHLRQVSDUeqHyrCMwa/nU6wCnrnjDkhRYkxmQrFTa5gcZnRlXlXtDlKnX6gXxzkcH4ZLk8UTPXRlk73fiz6LobCX1iregfgSIELBdBwAmKLXNXXvXXRTxtXX7LVtpnLbU9MX/BVrbXlAzlRjg4ETuAwgWFjWI3mSvH8kCFHWHbUaTVtRTBDWdYUSSqUKFVjm4bYAu614VzN4ydFJ5ZHtmy9bH +0rWC9URDX1ZW3/nAng9aWSpgaQVSLp5iq9nTq7UoIn63VmPGG3WpaDG3X0JUepWg0oFFpor74pHhpGXBk0/7zWHBZJdzVdiUtdLhpUFbWpBDO3XEQDuUVu3XnBKHXDdoCo8LsRDuaALSpZCDKBl0IDNVjP47i3WAXCS3X76T6OkNEBDGSyBAx3Ufc57Xby7WJSVVdVD7UDZJmtxywLF+Co7xF9F2zCuMhMdVqyR53XmgkF3U3ggpnWQbEtWk9zU0 -3WQnXReV3rUwnWXbQ2YII3yekDAthGzms8yspCf0wsxVP3GwpDkHVUzUSEU2UCBXUvVWvuF0dWIeU2nVnDXxZb4ZAjGa+DBqPlQCTv55lrnFAS/nWBW4J2XSurpBmwaqhU4HQXrh6gzFJ5YziFvSlFJmdg5Uhm0am8bl7mGR8UutnT0Hd8YY7VJ2WdCWzWFG1VrNnscn7tl1FzTqr5bTTmoO1F8LV4dwq6FPbX/HWBwTUIWolFdHmIlF0QVjLUpU +XX6zWSnarMXSTWlKWWWEbCUYrUk5BiQDOGGIZnt3V9aiO4BPiwQMIHXCygAgExr0ThQRw0wTyF10letDvlTGGIiuFPoBx6lhxiy3X/XhATAjuVhYWBkWc1WzqW1CWR7WEDUuqHO9DwuhPHlya4vUYmsF63VPCAG3XnHiF3WH3UZcWFyYHTVWNl/Zk1+W6TrPJnXOUN1FEEWpa7J9URuFkCk7NY0PW2iVMJWFIb2yYk+xW16IzVctWgjWLWX7hnV1 -UhW6RRVu7UyjYa0payFhfROrBhEoyUD3ySY8K96iU46+9rpCVx3W2DXEXXnsUs3UDVYCDXBGbmHVz7VPtVmIVGOxZwICRHbKXBsZiCJzhjPSoedVDNICHXimb/w6H+mVDkUDWPXlbmUThL4bXGhw7cr+IKZ2CvOjZ8VsXg4agqGC7UCTbVNhmNtXx3UtXXrdUT7WpjWCjlVSVW3VKBUA3UDBKGiwcnhV4bs5lO3Vu0onxguyi/nU1OjVl6iNVDwb +UWBF6ZUFD733VCkDIHRP3Vq6hCTy9NIUgwtWC5EBSxQYbTFHTQIRvxBmLXYGWjsz/qbgGWfbCvlQgdJgPUyQDiqwyDUFDEBEUh9UMrVdbWKDVmAJB0g2PCkDX9KzERr6SJE4y73VUon73VAIn6QVnQFuXVKl5YnEpXX+wUaMFWDXbJF11z33Uu3VOwCCPWEsy7egvrlH1RiMJw0wfiwsnEPhhwOg1lXClhM54KuCE+QLSWjmST3VXsVKgTyph89U -ix7DG4t+mOJWIXXaDWQ4XVHWsoBd2J/9i+KALFwFhCLXgtWAXipuxjtrU+EVSPXT9ViVWmUUqE6fXXLCaHDUEwQ8lV/hlRWWbhDX1gGTw96BysQ9FV1B48qhNSUubWtDVzokb3V9wZoOU99ZLhkxzlbKludmWd4c9Uw55YeyCGmmcGIO4gqST+nl06nDmLnVFf6KQJRUW3A73q79w5I3XqDlbCHKDnKDZztUbnUN3VgXaGDk7nUlEhHADR1AKAio +KXjNHU7dXweUDBINADRDU9uGX5wUSV2mVl5wiPxVdQYPWqkBYPU5hgH3VmdIWN5sHWPGHgjUmJbAmmvKUrGWINVt3n8WWMWZGDWfIJjmklPkYsWPY5O7VMSxuPXdsD3cSePXBY5f4UHUBInYzahc9KrG4wxA3EKOlVncpxt7hPVAPXqLhySBKSWaOgJPBi0Q4c6I+7z3X6uUMRWduAf3YFXZxQhpkAPzmPAEWuHQWR5PW1qAFPU0uRWPUMHXFTEW -wiwMACUSsSCn8Bq+DDjVupmkvmlPVMtUm3XBWWNzXhOIIkUhXWiOXEnXZjXAsXscxAKlibjb9WT+bVSLVkA3i76PVlrDL1ba7ayNXeCYoPVi5mWWX5u6qWX9w6WVoTPXgnWfw7DAEf5bBm4jO4S6GpTkCLWbmXU35SBnX7V7mV3tBeuAN+aq9y5niOzyxfRTIQtJ7rsR7sng9VQVXG3UVKCJ3UmbVmQH3tVScDUXV4VaSxIzumc7CxVU29XA6gwr +IHUpnkP7VKXAoKZukxuEkqmniZNPXzHrHnVaLV33XgQAyslx0XdkzdPUAki3GByXQiVxxdAVCCMBKPjpMXhsep0cywIVq3AS3WIITj3Wk0kShE7WTgPWRb7TvxbaEPHXBc4yoC8OUyBjroVzyklikH2GLlxmPWYPX53XYPVFPXHxFTXXVUGvuWuoXu17VWkOib8MU4CHyinO3XdsAZFjvPUWtmmJCEaFBZw8gCgkhMRB0SDfFDwbDfbmY47RTw75 -LLY6/nWzM6l3WVDkSrno8k7zn8XVh8kA9Zor7eyWsLZ+0adw7jYVdlnSCEmzycFaY1mvs6T8VaDUrHX1oVqzU8UT5jzCgAL0Q0RRUtxxDiCMxY/lS4w5+mGUVhwXWNXEXViTUxTULbXTvz4XKkLXrqUChXAHU+2LUczUCYhyhOtV006GRLe3D7ygr3W8HVr3XRsRcYJ6lWMEXjdmRNlBRVaanZemKQLnOXlnVFXVLCrK3XIbR3nQFNQ9Eywkg/9D +jUiylYkENWzPW0HDHyHL067sVEkUmxX0rXlLWPHWkjVP6ATgDtznLwV3cxlbnNqh7PXVSmWPVF3VTnWFvxxlWJxkPOZN8m7jValYSzBn4V8rZ6T4GYUWQ6O7UkxJX9kBXVLqFFSG/SmfsWLqZwNXuSWP2VhyWvelsrk5gRrLHMjWDXkqlb80xRTVULVPPWQnUFyVvPU3Ci3IxnXJserXFKpYScyBbUBhAByABEYQG2UYQXSRAKPWH7yz+UYrkcuH -Y8InyB/azOZC4WColmcDVXnWmvWfFVzwU67XexlLlVMvU53YTRi+MHyToZOASFF/RiB2yQ3X3LXQ3WYaWlHX98UBtWiflqNXjeluOnINVXrkUcXbcVwx5NvW7znSmzYgXp665pX5cmSUBAZAodjVDzpfKOFzNACKJwWzCmzDFUWPTmnHUK0XlsaVPWYN7BrXWqDNFWhXXvPUjrVVYUnUBKNbn2E84Q+KjK0LY3SzGQ8vWe3UprUY9kgtW/SZrTVc ++OHIdxG6n0iHJPb97UK7WjFVVzVozJoqVVmXn+4n4huwWZuCYlj9HVw5TmPW9slKvW4PVr/5s3lxmFLYH1C4P1yJJk6sUQtW9IRerAvIB+9Q0vWGFKuvyBKAEgK4Cy3OhYEhOqAhsgLAQ16EQ6Vpl4TPUn4jAPVFzklQhT3WxPVJvXEnYNr4J3UhnURjW0nUp3XRjXgkCWnnoPXU7G+H7oLgcaXpbzFvXWcmlvVmdJeVWTHlc7mpk78HFk3UsJXA -CWiZkOHG+zI7l4Xooi9GdbWUDV/NWYSDrHVy9XoMCUjwWITaihUrysDQXDpa+J/JCybqQjWjjVUvVnHVkMD1cXyPVnaJLlXorUyrWryXMvVaon3RZ2FCc6aMXUTOw01Ri4C/nX+OFJBUSfYBnXdzlzzkKdnikbyDkrBXXvWVtmTqnHNbDznddV89WEfW2HEobVrnWi9WSbWtdVQGXSAXV+5RzmudlNFkpFGkVUTt5era6g55lVOzJ76laWW8HFdF +uVfbFVublLHgjClBmMYFoFEZQXJQUFOpQZHmIzLTFvsUUvXgQAMDkT1ItvVphCVCAEABZvjwwSZcA7ODG+Q9/zL3gSqAZ2Vh6UcjBcvVj3UnsR50p8vX/wjw37bPoexaJPVVrUtGVdbX3/ma6Au2WC3APzkUpJDlrjbAKvUmyk7vV+TXZKWXOVKpEebXOqbeaGE0UfalGGUka5PbG5bXG4ajWH+JWH1o7hUpkU9CUPTlhDH+mXhsWIxVOGGlorGG -zzYEnznUxnTMm0pktiqNTHjNFUfX4dn4MX2iG1G76lU47aGFUTFkcwVtZX71VcBVAbxH1UDqWKCWrHDQOhWswj06U5CaokcKhtWCV0zv7VPwlGKJv3XKLV5zna7Wo7VR7xqz6HLXdtXqVnhrUqyWhyHOrH18EGjWDplonzCcBAgQevVQ3VHbV85Y9PWVCbmhnXN7JTkjPU9YVkDURuFiun4J55XWBe4pJGQrmJxlnXV1t6F5IkjXQrnRfWbPUFXX +VN3UQMAdPXXZD1dIfvW+xCQmI7YLSx5xIw+iBT3gfbyn1jNbqFBDzrXYGU6B6R8ExvVXPJsklR3XT3UuHCx3W5wV5QaMCUmWWfnVw7V0nUQTVQdGzppCBhuwVFGTkjQ4fVFRl4fXl1VE7m7hGVJ6CE59pWV2npXXaWK8fX4hAjrQCfU/RDbohwMA+pC54D5YYuQLnXD5JHI3zX1TO8G3XGgvXpnCQfX/WiqPWogDqPVXTYLq6beVWNWivV1XWR7U -KvXm5WRw4RfV8BWOQAlBA/JBxhK6WKMgASsrO/htJHYwmfFIGfX+XX59V0vWBhFLrly9CgfUc3UnLUH86VwTcbWkrFoXlM0k6GYDEBaPWJXXfHX1bA1cHJ5nhMGrHXlSErrH3KWflWxSVfaHQjYl3nugGoZUpNVAiUknGqg7ytXqNUC+Vt+UKvmSB5mpnCeG20V4dlcLWBxUsxkbhXu+wOXUPxacyCclhPPAw6BCTzCUAP+xA9IKAh05D92nHzUa +KTlV/Fe8IqhRu5WOWTiBgtrX7hxbvWoinmfU/tlcnbxT4PcHRXVJoFcyUSYpBTU50UFfXByXfrrV9Ig2X1vV43iOfXlgyzBn7wDSErRAzM9JpEAtTi0czCoI6FDR8RvxDgBAD6g6TDgfVgvVZTUtf7jvWJvVqfVKnX2L6VrWdtV3zVkQXOrDvTGmwkwTVCqHU2irHCOQDb3VFvVYvV73U4vVHPVrjXzKrsPXE7o3vm0cGjtqx5Zb7V8jWK+D33Xb -7Xf7WMkK/7XUZn6tERpUG7UfPV7CVvyRVfTLJ4wHWYeWYP4gKB5SS81VyEmw3XCFahsV8VaBmZQZFyikdfl9ZmP0XbpA9vWuYj33BurSMobmFCv9BnqDPsBe5ZLZnkCo82mbDV+XWdnXGbUWzVjhypjI2zU2vWMHVD0n2vWtUW2lhwhgipSzoXifyVknvfVy8leUX0EXPLYRLbh3qxMX/MBCTYJsWwNWgyGTpaumXcIYymXs8gHPVeiDOSQowjK1 +pCHMAufWsoBzQzbqD2CiwxA6JCcOTKEg0RTwoBCgCAvmmoQj3VyyT9fWyrmOOExPXDfUHBrwdLB9VM4VfnXw7UlTUxji8ARwCQJYWUuVifE7HCmfUf/nZfXHPWVWlr8WxP5dAGbRXxXUXwVPN7A9lUF4Zple8lJrYg5ZL7XN34LxU6p7NtlcPXj8F45W8PXPPVCkCa3rnfWzmg6iiIXL+cyQRpgmQLARwOhJ8Rrmi1EXE87cHSh3URPUjvUA7Qxe -J1UIpo64IDUMGZkEBirfTI3rEAUmx3Vf7UJ3Xh7XePWpaJv8Jm7knDWr9XhXVLvYZrjHmQd3Ib4ChgWMwgqrDlvWkrV8zWBtAMnVphFjZmVjUGiHoQrFNYYeYBm55zoZBWn6bIaSmoxuE5LHXHXVFXW1DmYSAYHW0uWe3n3tClyTS4W5lpRgBDfzEAbL3jI6BFskAUk5DhG3X/vUDjhf3Wp9G0HVOoBWnV/3WvpUAPXMvXyTVEZZQipYQhxVUVdg +DKfUTvUjfWEcWsqFaPX/fU6fUp3ULTUcQKHSx32DNzm6cHhKXgVJQ/WyYUw/WbfVM9r5IHaeUE9UmN7OFVuuWNJnOtXX6H/YWuPXPPUn+ChYQU/U0vG/ADNCTUuGkfSs9BNDCt4CrWKJ2xabUL4S+mlfkEak7DvVTPUBDky3VQvVqPWf278/XwvVUjZAeVGviafC6ECONVVMY8KCGyky/WGcVy/VDTZHXXjtn7L4yCUgnVMPU8XlZ9X/5WabKUvV -nTD+DVfHV1LX1aR9rF/HVAzEdl7AdUhPmyHb7um6HmMPXqmEipU9KZKJLVNgRckOdnuMYOCFXWal/UkqSV/Uw8mxeFl6pWEXtZW9eUzJXyCCcexUzSg8WNmQXuLlp4uk5mBLOTY97RhlC4EgirLALkirXv3XL4XpOnGfVx9lt9r9HUbqWW+X2vWd5UjRrCxCAFLA+KQ1ZyrzWsS81Vc27/nWodEymZg56A/U11ypV6IPopMVujXoQVOPlGF7T+Go +8fUePU3CgZrgY8y0cwjPTeuBOqDHvT3DpSoDsGydRXvWg6O79WY9pgVZjFrWffUJvUz3WKjXW3mmmX39UTfVwPWqHVUzWUJBX6QxwRPHlgkIpGCEtmbvWrfUWPXrfXKvU3VU/XyKIUgywJTns3Y4ZXhbUDamxZVVx7nmU6hn3RldLXqdHSalEBnhe7+iXM8HNGFklXIeB5gUewEQjXL/XXPU33XvuUqJCNvWCH6vvVNiT6/XoADO4B9zZOmBHXBC -SULvIbTUaCFUyX4wGgrmAdXnV4vrr7brNvbEpEkTrzGkzpUtLW4ik2WkBZWRfWaF6d+U+VHS9Gx8Vy4ZtebG5XfV6AA30VYFHk9nnOgFwQpYBH7/k5kV9jm15FH7k23kt3Ys/XhjAg/W1HAncjUMF9oAXsB0LphKD2NCvTQ7rSeLHxin7LlD/WGfXNTlJ3XVrEp3WBQXvuEhBX6qUnJXX3Krlq8wpZC7ehVfcmlPK4qrTsSr/VQcQtH4JBnUtZHF +ZJhTS6zBdVi5ZChlCizWcryPx4F/UV6TgvVB7XJxjQfUq7AId5h7UC/U/qVC/VTfXKzVuyDTPiDBXz6WFbk1RSUvCFvWMEyZfUTazB/VCAUTlUflUuOk5hXBgXjOITbUPZLwA3DrVX8jb/UThKJ/XwdUztoWszKEg/NBI9jmBI5mzCVQJdCskYDvUAPV2/Xh3WcLXIkjP/UCvXUaWThxLPVKtVnAVCdjjTI2yH2MQHOWvQKKfDlA7LfUgA3t/Ulv -X2xJSNX2gZ0PWNwDxeHNeIyl7umrC+kd0WPlWBEEyNXolxt+nTfWjGm8SlTfVLk4IcXFrKW8VtbEZhEEdmF/ZsoUvn5ds457WR47zfXD9wReXkfoO4We06f3mzqbKNXHzomA2R76iXXmA29RUN/W2OU8jVs/UXOgjFiSTDdLxp8BvKqtHAqGBoWDhRlrLUD3UdnWmvWMtlqLVKxLzoqdgXWnXh/WZ3VqPWszXUCi/bD6RXJqwtnkLuxl2gedVcBg +Wd/VlvVbty9CWjcGDflmaWTCWR7HWIF0XVy4YztWyRUxyVu4UbuVXZKK/UEilirYYAVOHFr9VF0WoXWVhHdEU/nlKlWyrUwlH0XnbGrAAVybWwjXIA3gQANzAdVF3LL7/UQAB0gDF0j2xixZioBDGJDdADBkI5BDkfTC7WgfV89B9fXBfVkA1JJQKgjQvXqWn09FGdXdnXw0XJ3VTfUqQWEEAt2Ad/HNzlPVIrYmxvWTTqgA2sZjgA2MGVVQ4FTF -eZXM7EebUO0WUSSkIXgRwsPVvuakD6A0aswXzMUCnbhFYvxVpGZ5eGO36/HYpDqmJZz9bMpKxaGmrXc7XlzqVylSta2M4TenR7G205hl5oSVBnV37IGM6mA1jzX335bqwnxFB6aLXV07o4qlxW5JoqxjSxsXGvSgVAW/WKxXh0qqkaLvKcZpz9blHXQSBMnXTKwxaWihrLfXRZW12kmrXCmVWFQcxEVHVcBWLy6HUyRvVkqprUAW4DP0k6jgcJqB +rDUGEVSTXnvX5eGS5V7FUlDXttkQnVCCXNPWkeXo4Fh76/dqm9khXXVeJJA0Asa/xmhFGwdXvFX33UZWCQLKmA2XLimWS8SisIIyXTnGBXYCeiLd6h0IDP46BfWj3XvfVF1T3yphfXtf60eEjDWWNX2CVqXXzvVTfUPzVqEhKfASkoeTX1fRoOD6e7xnWp6hRA0xxkxA0m3XqJGqqHisUJA2rDX2fVGYKVA1GKBEaSmA0RTTn1heSTcpgONC5CDT -TwsILzTDnqCspB8cUnHVjjXUvVpoXUOIkA1MCGjeF5vXy/UwhmXwYssQH5CfhX8oaYZi2jhOHWp1gJA35VnCyHd4bw3XW1VqZm6cXVVU/NVXtm89WKsWcJJ2b47lJ92FcVHArnSuni+neDH+yTVNLvwVqZWoXVRn5lMwblj1AD2ChNEgG6j3GACWzxkTNWA7JwW6Wi/VQ9UhlUS/XeHkp3VW5FfKK1PVXLnxiWNeBIWbOxq16webBxVVEGE0PLOb +3gjjBWAAG+BA0UVvhFCxs/WTPXknU6OAUA2jsG0TVKjWuNHBnUfnWhnWf/XxZYTWwpyqEHLyShg/WydghmREGGB/UHPVG3U8A26vqELHQGWvP58ZkWwFIBHJMVzmE8XW59VluUpeHZD6eqU/jGtPU13WLAY8dn1+X1bq1fUjgxEwCmA1haD4yhccpz4anOBFHTlhC3sC4CzbLRenUVvhwVYuA2aGT/TSPsQPA2wfUo1l5QYzvVvA1zvX+A2fA0iL -VnBi/+Cp6ienWwYY7jUs6HdfXBqEVrW2PkLFWmmlkkWv7J/0E9Kn7FISZUTNVzjyK7aTvlzgXKMFDdVi7W9eUvIChHVq6gaJycWz6JCXyDe/hLARxDjCGLaCrSgA+Xl+3Fr3gFfXI/XS3l+A1J1UnZwJTWWHXUCWDFbbRi6whlEq/dlhjyYkDh+h4yU8g0CNBN9X+zxU7Vr/717k77LJPVomX/bVP/kB3Xk9BrQKc6x52ruaBuuCc9CbRjX3C1uy +WHDD0iTK6412XzWBtrDAA0ZfWcA3bvXcA0ZjW5jX0pmgo7EfWmDUC8rglHLkWpA3uvXbHXHfXPPXbpCQTR7A2zYCCfDioDDOYLdStsy3lR/JCXPxd+Vd+qZ4LyfXEwmKfWwpCMg3wJw0WVjDW1XXqXWR7UuLUKGxoOBKIDNzkVEqM9V//WRA3Cg1ZfWig3LFUDLU3V574VtAU/xnTkVlYUu8nFiGrtX0FJXPXYsWW5G5hWh1VO3XgQBCkDhg0R6C -+kBwAnuPUyPVD3Xi/VkXUV1RrnlBQWUA2rbXUA1ozKRZgifT25jeeXGpUAOqtBgLIgQ2Ceg2wTDeg1KtKStXhFaSJ4qzXPnlqnXKoSedhZBAiKhCgDDjIhuCcvha+AigAXpn2AmdrU3A3+/XPUAAbWF9VMsV0vnEykNNX9nUMdUR/Xm9X9tU98CG+5KomhgVVPGveiY2Xlg0s3CVg0KeUHvVVmVZjkCrYZ8G2kUjzHCeF11ERzU17WfjWcPUQCBX +mA3sGy3bSIMDThpvxCNbrk9TbLSd2LAjTocVipjUajRvUmg0msgNOyjhUQWQv/WQPX1xwIfXV/WDxWR7WV5XFrTx6RHdU/BUF05Vonjdlt/X5PXYvWFPUbfUABpKZmlyXc7EJmEUpl3jXliGzhXKo6zWEYFLorWb/VKg0QxXyCDds4mA03CjI1BwWCIxGwcXjYCNgBvMi+cToIDvrVAPAS+zaIFvfWuA3WLUl/XR3WqfVlwnS9ImqWC/VdtXhnVA -jEwe6PjIHNkn27+kDSUBwgCrERwOiHgwjgFRhL+QID/XxjV9g3TvXXtXmvXZvVAQ49d7mfXapV7dW3fUSOWmIRoSn70gn4iczXdpCe3BLg14RC8g2a/Xcjrvxkmpm/FlPbEiIVz57SdUkjGSdWUd7LpXn2VzXV/jRxkURn4YsVPdyyTlzpkzflkjlS9WCkX2rVB4B2YCxGAJ8BRABNd5oAAQIDQAAwgAZACFEDcMCrAAMABtWBoIDt/SvLHsHScQ +rVTrnIjxDdnWUX7rD/NSPLG53Xug1gA2eg1EL7n3WweEigHqmFd9mVSUu1H9iwG2nOCEk/UhW6DiSmA154AJEBPjxwWAz+hcWZQcmsIJi4wERwZlIj3UgmD3pivlT0ioAA7OpgJOC8/XZ3HQeWvA38kEGUHaPVivUIvV5FVBbw+3g42RcCVZ15UpIErJAg2tg3W4h8FArDWxDzlQVrxUFjWSJo0fVjAEwg2ReU5M7gabs0WstWtKUXBnuVk3BnJz -1cgCGrAiACpoAsljpADqgBFn48Q0koAOID8Q2svxeWrCQ18Q3zgBZCDyHSSQ2iQ3SQ2CQ3cdhyQ1ZABiQ2KQ3/ULKQ2I6DSQ1XrIlYgaQ1iQ3vpjwYi6Q3SQ1rghZAAy/qP/ry/oFACGQ3pADGQ3i/oYAYRFolADaFAiQ0qQ3SQ2W/q//rBkBq/rcQ0OQ1SQ0CQ2ALxeFCWuB0kCWQ1ZCwgLy+Q2soCSOCKqABQ3+ECYiwQpAiAw2HncQ38ZQUgA +Vgc5iQBH9DGA1jqqmA0FKw3sCQGbTXiH1gT6JkyTIbD6IhsviVHVikR1JgJHA2UCwQ1x6mD7A9Yk9kV2NRItkjDX6dUMTXkUHkEEVg2EpWR7UTFWa6AQFE37q5Rm4wmGYi2jiYvUtg1rfWH/GCujW6mjLWXAj/EXXSFmEX5+ZYrRRmzwZGe7AwdViUogsEeQ0tKXFnW+8VILAnfULLQaQ0NfVakxLgiZvgRxDKVCfLID7wUyCcSirghLdRIDIgvV -qgDUtCi5VYBDmg0WQ1xQ30gDqnZhkDyphNBi1XEK1BZOQlAAY3zblg0Q1tIAEAByb4egBWkABQ3aQ37DB6gDApDFBjcQ0CgAkABn/qS/oWQ31Q3MvjzgDRrDcQBPWBpEbzYBRTQAiRZrDmWCdQ2sBCp4DoIAhz7bYAJbG4AAAAAUMOI6hIj4A00N1AADkgAAAlLqACdyJMWA1gDDgMCUDyAJNDXW0FVmCSANtDXNDYEgItDeVDZ5DQ4gGpDZSIkq +5PYKQ07emgPUjuE0PKngiZ1UQ1U+A0XdTC0HjDUjA2fA1IlUBTB6dJLFXHdV/M7c1ytVSQoELA1UyjnHiErJGnV09JiZbasVowJstYCGnoRlljUYbly5UQQUbBVzXU9GHnUVSdXcfVJCBerB4+BPHSmA3xLTTSISUAm+BKGBxdAljQEIBQ6CDKjSQ2QQRdsKF3ZHgo+JnTPXJQ2GolDCRAuEFwFwEWx/6e0H25U2g2qHW1rUuQjSTp0zWkGbf44k -QW2APZKD9MCdyNmAIK+CQ4KngJkAIfZMEAHUgL/4F0AOzGns8ACJAxDXs8MIAH7KgWsLEIOVDXYAKCkrtgJFBACJPG9N1DYW1A9Df1DbyAAN/IwAItMEXmkVDefxNoUGSAAYAJFDSQgNq8puwBTIFDDQW4bDDWkEOAAIlwKdYEFwMAAEHgCAgEAAA=== +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 ``` %% \ No newline at end of file diff --git a/多体求解器debug/明阳机型转速发散 叶片变形量为负.md b/多体求解器debug/明阳机型转速发散 叶片变形量为负.md index 18dc1be..f153055 100644 --- a/多体求解器debug/明阳机型转速发散 叶片变形量为负.md +++ b/多体求解器debug/明阳机型转速发散 叶片变形量为负.md @@ -4,4 +4,16 @@ 关闭叶片柔性,转速不发散 -思路: 判断是否由于叶片变形量为负导致转速发散,尝试从叶片方程探究为什么变形量为负 \ No newline at end of file +思路: 判断是否由于叶片变形量为负导致转速发散,尝试从叶片方程探究为什么变形量为负 + + +p.kbf +p.cbf +数太大了 +明阳机型是nrel 5mw的100倍 + +p.ktfa +p.ctfa +p.ktss +p.ctss +明阳机型是nrel 5mw的1000倍 diff --git a/多体求解器debug/误差较大的载荷.md b/多体求解器debug/误差较大的载荷.md new file mode 100644 index 0000000..1cc95b6 --- /dev/null +++ b/多体求解器debug/误差较大的载荷.md @@ -0,0 +1,54 @@ + + +- foundation fz +- Foundation Fy +- Foundation Mz +- Nacelle fore-aft displacement +- Blade root 1 Mz +- Blade root 1 Fy + + +# foundation fz + +```rust +dot_product(&frc_t0_trb, &m.coord_sys.a2) * 1000.0; +``` + +`m.coord_sys.a2` --- Z + +`frc_t0_trb` Total force at the base of flexible portion of the tower (point T(0)) due to the entire wind turbine + +`PFrcT0Trb` Partial force at the tower base (point T(0)) due to the turbine +`PMomX0Trb` Partial moment at the platform (body X) / tower base (point T(0)) due to the turbine +`FrcT0Trbt` Portion of the force at tower base (point T(0)) due to the turbine associated with everything but the QD2T()'s +`MomX0Trbt` Portion of the moment at the platform (body X) / tower base (point T(0)) due to the turbine associated with everything but the QD2T()'s + +# Foundation Fy + +```rust +-dot_product(&frc_t0_trb, &m.coord_sys.a3) * 1000.0; +``` + +# Foundation Mz + +```rust +dot_product(&mom_x0_trb, &m.coord_sys.a2) * 1000.0; +``` + +# Nacelle fore-aft displacement + +```rust +m.rt_hs.r_o[0] - y.tower_ln2_mesh.position[[0, j-1]]; +``` + +# Blade root 1 Mz + +```rust +dot_product(&mom_h0_b.slice(s![.., k]).to_owned(), &m.coord_sys.i3.slice(s![k, ..]).to_owned()) * 1000.0; +``` + +# Blade root 1 Fy + +```rust +dot_product(&frc_s0_b.slice(s![.., k]).to_owned(), &m.coord_sys.i2.slice(s![k, ..]).to_owned()) * 1000.0; +``` diff --git a/工作OKRs/25.12-26.2 OKR.canvas b/工作OKRs/25.12-26.2 OKR.canvas index 68b96fe..2210445 100644 --- a/工作OKRs/25.12-26.2 OKR.canvas +++ b/工作OKRs/25.12-26.2 OKR.canvas @@ -1,14 +1,12 @@ { "nodes":[ {"id":"8359617e1edc48ba","type":"text","text":"状态指标:\n推进OKR的时候也要关注这些事情,它们是完成OKR的保障。\n\n\n效率状态 green","x":-76,"y":-306,"width":456,"height":347}, - {"id":"a4eaccbbfadaaf17","type":"text","text":"# 目标:\n多体模块完善 线性化模块开发\n### 每周盘点一下它们\n\n\n关键结果:多体动力学建模原理、建模方法、线性化原理掌握 (9/10)\n\n关键结果:风机多体动力学文献调研情况完成 (5.5/10)\n关键结果:目标工况测试、稳态工况对比 (9/10)","x":-76,"y":-803,"width":456,"height":457}, + {"id":"a4eaccbbfadaaf17","type":"text","text":"# 目标:\n多体模块完善 线性化模块开发\n### 每周盘点一下它们\n\n\n关键结果:机组整机线性化模块开发 (6/10)\n\n关键结果:叶片、塔架station结果输出功能开发 (0/10)\n关键结果:整机瞬态仿真初始化功能改进 (0/10)\n关键结果:dlc2.x剩余故障工况建模及开发(0/10)\n关键结果:针对软件认证所需输出变量完善输出功能(0/10)\n","x":-76,"y":-803,"width":456,"height":457}, {"id":"d2c5e076ba6cf7d7","type":"text","text":"# 推进计划\n未来四周计划推进的重要事情\n\n文献调研启动\n\n建模重新推导\n\n\n","x":-600,"y":-306,"width":456,"height":347}, - {"id":"82708a439812fdc7","type":"text","text":"# 1月已完成\n\n\n\n","x":-220,"y":134,"width":440,"height":560}, + {"id":"82708a439812fdc7","type":"text","text":"# 1月已完成\n\n\n\nP1 检查有没有塔筒上所有部件合并计算质量、质心、惯性参数 -- done仅有合并质量\n\nP1 明阳机型验证 \n- 叶片发散 叶片往前位移 原因查找 done -- 刘\n\nP1 明阳机型验证 \n\n- 商业机型模型验证 气动建模有问题\n- 中性轴问题 ED当前不支持预弯叶片计算\n\nP1 机型测试\n- 模型对齐讨论 done\n- 1.4aaa 工况设置问题\n- 明阳、NREL 5MW跑一轮计算\n\nP1 给方方姐回电话 done\n- 商业机型测试有结果后再见面\n- 建议双向了解情况\n\n- 过程+结果,年前 建立信任 现在是副总师了,站位上跟实验室对齐,计划增加王老师从技术角度汇报的渠道\n\nP1 服务器 ing\n- 机架 - 浪潮确定\n- 电源 - 电工给方案\n","x":-220,"y":134,"width":440,"height":560}, {"id":"505acb3e6b119076","type":"text","text":"# 12月已完成\n\nP1 明阳机型验证\n\n- 商业机型建模 done\n- 正常发电工况对故障工况支持 故障建模 done\n\t- 超速n4 普通超速 多体设fault结构体 \n\t- 卡桨、 控制设fault结构体\n\n- 故障工况检查 done\n- 批量计算更新配置文件,风文件,程序版本,再计算 done\n\nP1 稳态工况init_with_yaml检查 done\n\nP1 前端\n- 所有simulation功能测试及对接 done\n\nP1 演示ppt补充内容 再补充\n- 补充steady operational loads / steady parked loads 缺结果 done\n- 6个算例的跑通 找一个与bladed对比 缺结果 done \n- 内部控制器 pass\n- batch 并行计算 单个工况是否快 多工况并行 暂时不做\n\nP1 前端\n- steady输出的名字改掉 done\n- 批量计算 改成并行计算 功能界面\n- 瞬态计算更新控制器 测试 done\n- 简单内控\n- 比较Bladed与正常发电工况速度,总时间短一点 multicase done\n- 是否需要增加相对路径问题 done\n\nP1 dlc 71 done\n\nP1 输出量更新到Bladed相同命名 done\n\nP1 专利 done\n- 做出solidworks模型,写专利\n\n","x":-700,"y":134,"width":440,"height":560}, {"id":"30cb7486dc4e224c","type":"text","text":"# 2月已完成\n\n\n","x":260,"y":134,"width":440,"height":560}, - {"id":"c18d25521d773705","type":"text","text":"# 计划\n这周要做的3~5件重要的事情,这些事情能有效推进实现OKR。\n\nP1 必须做。P2 应该做\n\n\nP2 柔性部件 叶片、塔架变形算法 主线\n- 变形体动力学 简略看看ing\n- 柔性梁弯曲变形振动学习,主线 \n\t- 广义质量 刚度矩阵及含义\n\t\n- 梳理bladed动力学框架\n\t- 子结构文献阅读\n\t- 叶片模型建模 done\n- 共旋方法学习\n- DTU 变形量计算方法学习\n\n\nP1 线性化方法编写 ing\n\n- 开始编写扰动代码\n- 形成系统矩阵-输出矩阵\n\n\nP1 明阳机型验证 \n\n- 商业机型模型验证 气动建模有问题\n- 动态失速计算慢\n- 叶片发散\n\n\nP2 气动、多体、控制、水动联调\n\n\n\nP1 服务器网络申请 ing\nP1 报告更新到0.6版本 ing\n\nP2 bladed对比--稳态运行载荷,产出报告\n- 气动参与模块对比\n- 模态对比 两种描述方法不同,bladed方向更多,x y z deflection, x y z rotation,不好对比\n- 气动对比 aerodynamic info 轴向切向诱导因子,根部,尖部差距较大\n\nP2 yaw 自由度再bug确认 已知原理了\n","x":-597,"y":-803,"width":453,"height":457}, - {"id":"86ab96a25a3bf82e","type":"text","text":" 湍流风+ 控制的联调,bladed也算一个算例\n- 加水动的联调\n- 8月份底完成这两个\n- 9月份完成停机等工况测试\n- 10月份明阳实际机型测试","x":580,"y":-803,"width":480,"height":220}, - {"id":"e355f33c92cf18ea","type":"text","text":"9月份定常计算对接前端\n非定常测试完也对接前端","x":580,"y":-500,"width":480,"height":100}, + {"id":"c18d25521d773705","type":"text","text":"# 计划\n这周要做的3~5件重要的事情,这些事情能有效推进实现OKR。\n\nP1 必须做。P2 应该做\n\n\nP2 柔性部件 叶片、塔架变形算法 主线\n- 变形体动力学 简略看看ing\n- 柔性梁弯曲变形振动学习,主线 \n\t- 广义质量 刚度矩阵及含义\n\t\n- 梳理bladed动力学框架\n\t- 子结构文献阅读\n\t- 叶片模型建模 done\n- 共旋方法学习\n- DTU 变形量计算方法学习\n\n\nP1 线性化方法编写 ing\n\n- 开始编写扰动代码\n- 形成系统矩阵-输出矩阵\n\n\n\n\nP1 检查误差较大的载荷,首先确保与Bladed同坐标系输出\n- foundation fz - PFrcT0Trb\n- Foundation Fy\n- Foundation Mz\n- Nacelle fore-aft displacement\n- Blade root 1 Mz\n- Blade root 1 Fy\n\nP1 叶素、塔架station输出结果\n\n\n\n\nP1 服务器 ing\n- 电源 - 让电工给接线\n- 超聚变 - 装系统done\n\n\n\nP2 初始化方法,找到稳态结果开始\n\n\n\n\nP1 报告更新到0.6版本 ing\n\nP2 bladed对比--稳态运行载荷,产出报告\n- 气动参与模块对比\n- 模态对比 两种描述方法不同,bladed方向更多,x y z deflection, x y z rotation,不好对比\n- 气动对比 aerodynamic info 轴向切向诱导因子,根部,尖部差距较大\n\nP2 yaw 自由度再bug确认 已知原理了\n","x":-597,"y":-803,"width":453,"height":457}, {"id":"859e6853b7f1b92b","type":"text","text":"年底考核:\n专利\n线性化模块","x":1200,"y":-803,"width":320,"height":110}, {"id":"a850b2f46fa52de7","type":"text","text":"# 25年开发工作\n\n- 对标bladed中steady calculation,开发steady operational loads,steady parked loads任务流程序\n- 设计并开发 YAML 配置文件模块,实现了对 YAML 格式模型文件与配置文件的读取、解析\n- 开发控制模块,并与其他模块耦合,实现对32位、64位dll文件支持,完成变桨与变流器执行器的传递函数模型算法开发\n- 对标bladed中simulations,集成控制模块开发正常发电工况、启机、正常停机、紧急停机、空转、停机功能\n- 开发批量计算模块\n\n","x":800,"y":134,"width":440,"height":560} ], diff --git a/工作总结/周报/周报110-郭翼泽.docx b/工作总结/周报/周报110-郭翼泽.docx new file mode 100644 index 0000000..92efa6c Binary files /dev/null and b/工作总结/周报/周报110-郭翼泽.docx differ diff --git a/工作总结/周报/周报111-郭翼泽.docx b/工作总结/周报/周报111-郭翼泽.docx new file mode 100644 index 0000000..8eebfa2 Binary files /dev/null and b/工作总结/周报/周报111-郭翼泽.docx differ diff --git a/工作总结/周报/周报112-郭翼泽.docx b/工作总结/周报/周报112-郭翼泽.docx new file mode 100644 index 0000000..8d5d5ea Binary files /dev/null and b/工作总结/周报/周报112-郭翼泽.docx differ diff --git a/生活OKRs/25.12-26.02 OKR.canvas b/生活OKRs/25.12-26.02 OKR.canvas new file mode 100644 index 0000000..f1a5c09 --- /dev/null +++ b/生活OKRs/25.12-26.02 OKR.canvas @@ -0,0 +1,12 @@ +{ + "nodes":[ + {"id":"04da78b746646560","type":"text","text":"状态指标:\n推进OKR的时候也要关注这些事情,它们是完成OKR的保障。\n\n\n","x":34,"y":-186,"width":456,"height":347}, + {"id":"85cce24e1132f21f","type":"text","text":"# 目标:海龟 短剧 AI项目推进\n### 每周盘点一下它们\n\n\n关键结果:海龟系统现在版本测试 (9/10)\n\n关键结果:公众号系统实现(10/10)\n\n关键结果:文献调研智能体搭建 (5/10)","x":34,"y":-573,"width":456,"height":347}, + {"id":"52c483d4870680c3","type":"text","text":"# 推进计划\nRag系统、agent系统调研\n新闻 公众号\n小说推广系统 可能容易实现一些\n","x":-490,"y":-186,"width":456,"height":347}, + {"id":"0b25ceb1c28f6da1","type":"text","text":"# 十二月已完成\n\n\nP2 短剧流程串起来 部分逻辑更新\n\n- 拆分发布流程 done","x":-482,"y":240,"width":440,"height":340}, + {"id":"b79f3a0f35402ec1","type":"text","text":"# 一月已完成\n\nP1 海龟交易法 \n- 数据爬虫bug解决 切换成单一标底获取\n- 选股部分 xq done\n","x":34,"y":240,"width":440,"height":340}, + {"id":"1597ad15730745ea","type":"text","text":"# 十一月已完成\n\nP1 suno youtube视频\n- 生成音频\n- 动画 done\n- 音频有什么特征\n- 控制音乐时长","x":540,"y":240,"width":440,"height":340}, + {"id":"5aac58c184e57887","type":"text","text":"# 计划\n这周要做的3~5件重要的事情,这些事情能有效推进实现OKR。\n\nP1 必须做。P2 应该做\n\n\nP1 海龟交易法 \n\n- 9点28-29分开始检测价格,做出预备\n- 突破价格似乎不对-以及突破但是没有提示\n\nP1 商业保险调研\n\nP1 新号1000粉丝\n\nP2 短剧流程串起来 部分逻辑更新\n- 如当天收集任务,剪辑前一天任务,拆分收集与剪辑任务数据库\n- 拆分发布流程 done\n\n","x":-490,"y":-573,"width":450,"height":347} + ], + "edges":[] +} \ No newline at end of file diff --git a/软件组工作讨论/2026.1.6 26年工作.md b/软件组工作讨论/2026.1.6 26年工作.md new file mode 100644 index 0000000..5e6ca6c --- /dev/null +++ b/软件组工作讨论/2026.1.6 26年工作.md @@ -0,0 +1,34 @@ + +### 任务 + +整机线性化模型 + +newmark-β + +综合误差小于8%,内控所有的误差都应小于8% + +暂定20号组内评审,对比的报告和误差大的地方排除一下,如果通过评审,1月底找时间团队过一下。 + + +模型和算法排期 + +其他任务: +- 双风轮功能 董+郭 天成号,9月份之前完成,最好+认证 +- 批量计算功能继续推进,大批量测试1000-2000工况 +- 界面 + +额外提: + +- 坐标系与bladed对标,任务要列出来 +- 共旋先排上 + +batch python转化成rust集成 +与批处理共用一个 yaml class + + + + + +### 节点 + +1月底前形成excel \ No newline at end of file