元件的组合降阶——节点消去

前面几篇文章里,我们已经把 R、L、C 支路一步步装配到了节点电压方程里。

如果把 RLC 串联支路完全展开,它会有外部节点a,ba,b,也会有内部节点c,dc,d。完整写法最清楚,因为每个元件的电压、电流和历史项都能看见;但它也会带来更多未知节点。对一个大型网络来说,如果每个组件内部节点都全部暴露给全局求解器,矩阵规模会很快变大。

所以工程程序里常常会做一件事:只保留组件对外可见的端口节点,把组件内部节点消去。

这件事在电网络里常叫 Kron reduction;在线性代数里,它就是 Schur complement;在有限元和数值计算里,也常被称为 static condensation。名字不同,本质都是同一件事:把一部分未知量从方程里代数消去,只留下外部关心的变量。

本文先不讨论大规模稀疏矩阵排序、代码生成或实时优化,只用我们熟悉的 RLC 串联支路说明一件最核心的事:节点消去会让外部矩阵变小,但也会把内部节点电压从主方程里拿掉。如果后面还想知道内部电压,就必须用恢复公式重新算回来。

从展开的 RLC 支路开始

仍然使用前文的 RLC 串联支路。节点从左到右为a,c,d,ba,c,d,b,其中a,ba,b是外部端口节点,c,dc,d是内部节点。

RLC 串联支路的内部节点电压
RLC 串联支路展开后的内部节点电压

三条支路电压分别是:

uR=uaucu_R=u_a-u_cuL=ucudu_L=u_c-u_duC=udubu_C=u_d-u_b

用 Dommel 形式写成节点矩阵时,支路方程可以整理为:

I=GV+Ihis\mathbf I=G\mathbf V+\mathbf I_{\mathrm{his}}

其中:

V=[uaucudub]\mathbf V=\begin{bmatrix}u_a\\u_c\\u_d\\u_b\end{bmatrix}G=[GRGR00GRGR+GLGL00GLGL+GCGC00GCGC]G=\begin{bmatrix}G_R&-G_R&0&0\\-G_R&G_R+G_L&-G_L&0\\0&-G_L&G_L+G_C&-G_C\\0&0&-G_C&G_C\end{bmatrix}Ihis=[0IL,hisIL,his+IC,hisIC,his]\mathbf I_{\mathrm{his}}=\begin{bmatrix}0\\I_{L,\mathrm{his}}\\-I_{L,\mathrm{his}}+I_{C,\mathrm{his}}\\-I_{C,\mathrm{his}}\end{bmatrix}

这里GR=1/RG_R=1/RGLG_LGCG_C分别来自电感、电容的 Dommel 等效导纳。这个矩阵是完整的:它既能求外部端口a,ba,b,也能求内部节点c,dc,d

但如果这个 RLC 支路只是一个组件,对外只暴露a,ba,b两个端口,那么全局网络求解器并不一定需要直接把c,dc,d也作为全局未知量。我们可以把c,dc,d在组件内部消去。

保留节点和内部节点

先从图上看这件事。展开时,R、L、C 各自保留自己的连接关系,中间有c,dc,d两个内部节点;组合降阶以后,对外只剩a,ba,b两个端口,内部结构被折算成一个等效导纳和一个历史电流源,也就是诺顿形式。

RLC 串联支路通过节点消去变成诺顿等效支路
组合降阶把展开的 RLC 支路变成只暴露端口的诺顿等效形式

为了写成标准消去形式,先把节点按两类重新分组:

  • retained nodes:保留节点,也就是对外端口节点a,ba,b
  • internal nodes:内部节点,也就是组件内部的c,dc,d

于是:

Vr=[uaub]\mathbf V_r=\begin{bmatrix}u_a\\u_b\end{bmatrix}Vk=[ucud]\mathbf V_k=\begin{bmatrix}u_c\\u_d\end{bmatrix}

这里rr表示 retained,kk表示 internal。下标用kk只是为了和常见 Schur/Kron 记号一致;它不是时间步下标。

还要注意一个细节:前一节完整矩阵的节点顺序是a,c,d,ba,c,d,b,这是沿着电路从左到右写的;但做消去时,更方便把保留节点放在前面、把要消去的内部节点放在后面,也就是把顺序重排成:

[abcd]\begin{bmatrix}a&b&c&d\end{bmatrix}

重排以后,原来的GG矩阵会变成下面这个样子。虚线左上角是保留节点之间的GrrG_{rr},右下角是准备消去的内部节点块GkkG_{kk}

节点重排后的 G 矩阵分块
把保留节点排在前面、内部节点排在后面以后,G 矩阵自然分成四块

所以,分块公式不是凭空冒出来的,而是对“重排后的原始GG矩阵”按虚线切开。按Vr,Vk\mathbf V_r,\mathbf V_k分块,可以写成:

[IrIk]=[GrrGrkGkrGkk][VrVk]+[Ihis,rIhis,k]\begin{bmatrix}\mathbf I_r\\\mathbf I_k\end{bmatrix}=\begin{bmatrix}G_{rr}&G_{rk}\\G_{kr}&G_{kk}\end{bmatrix}\begin{bmatrix}\mathbf V_r\\\mathbf V_k\end{bmatrix}+\begin{bmatrix}\mathbf I_{\mathrm{his},r}\\\mathbf I_{\mathrm{his},k}\end{bmatrix}

对这个 RLC 例子,各个分块就是:

Grr=[GR00GC]G_{rr}=\begin{bmatrix}G_R&0\\0&G_C\end{bmatrix}Grk=[GR00GC]G_{rk}=\begin{bmatrix}-G_R&0\\0&-G_C\end{bmatrix}Gkr=[GR00GC]G_{kr}=\begin{bmatrix}-G_R&0\\0&-G_C\end{bmatrix}Gkk=[GR+GLGLGLGL+GC]G_{kk}=\begin{bmatrix}G_R+G_L&-G_L\\-G_L&G_L+G_C\end{bmatrix}

历史项也随节点顺序分成两块:

Ihis,r=[0IC,his]\mathbf I_{\mathrm{his},r}=\begin{bmatrix}0\\-I_{C,\mathrm{his}}\end{bmatrix}Ihis,k=[IL,hisIL,his+IC,his]\mathbf I_{\mathrm{his},k}=\begin{bmatrix}I_{L,\mathrm{his}}\\-I_{L,\mathrm{his}}+I_{C,\mathrm{his}}\end{bmatrix}

这样写的好处是,哪些量要保留,哪些量准备消去,一眼就清楚了。

Schur 消去的标准形式

内部节点c,dc,d没有额外外部电流注入,所以内部方程可以写成:

Ik=0\mathbf I_k=0

代入分块方程的第二行:

0=GkrVr+GkkVk+Ihis,k0=G_{kr}\mathbf V_r+G_{kk}\mathbf V_k+\mathbf I_{\mathrm{his},k}

如果GkkG_{kk}可逆,就可以解出内部节点:

Vk=Gkk1(GkrVr+Ihis,k)\mathbf V_k=-G_{kk}^{-1}\left(G_{kr}\mathbf V_r+\mathbf I_{\mathrm{his},k}\right)

为了写得短一点,记:

W=Gkk1W=G_{kk}^{-1}

于是:

Vk=WGkrVrWIhis,k\mathbf V_k=-WG_{kr}\mathbf V_r-W\mathbf I_{\mathrm{his},k}

再把这个式子代回 retained 方程:

Ir=GrrVr+GrkVk+Ihis,r\mathbf I_r=G_{rr}\mathbf V_r+G_{rk}\mathbf V_k+\mathbf I_{\mathrm{his},r}

得到:

Ir=GredVr+Ihis,red\mathbf I_r=G_{\mathrm{red}}\mathbf V_r+\mathbf I_{\mathrm{his,red}}

其中:

Gred=GrrGrkWGkrG_{\mathrm{red}}=G_{rr}-G_{rk}WG_{kr}Ihis,red=Ihis,rGrkWIhis,k\mathbf I_{\mathrm{his,red}}=\mathbf I_{\mathrm{his},r}-G_{rk}W\mathbf I_{\mathrm{his},k}

这就是 Schur complement / Kron reduction 的标准形式。消去以后,外部求解器只看见Vr=[ua,ub]T\mathbf V_r=[u_a,u_b]^T,也就是一个二端口支路。

代回 RLC,会得到什么

对 RLC 这个小例子,GkkG_{kk}只是一个2×22\times2矩阵。它的行列式为:

D=(GR+GL)(GL+GC)GL2D=(G_R+G_L)(G_L+G_C)-G_L^2

也就是:

D=GRGL+GRGC+GLGCD=G_RG_L+G_RG_C+G_LG_C

所以:

W=Gkk1=1D[GL+GCGLGLGR+GL]W=G_{kk}^{-1}=\frac{1}{D}\begin{bmatrix}G_L+G_C&G_L\\G_L&G_R+G_L\end{bmatrix}

代入 Schur 公式,最终的 reduced matrix 会变成一个普通二端支路的形式:

Gred=[GeqGeqGeqGeq]G_{\mathrm{red}}=\begin{bmatrix}G_{\mathrm{eq}}&-G_{\mathrm{eq}}\\-G_{\mathrm{eq}}&G_{\mathrm{eq}}\end{bmatrix}

其中:

Geq=GRGLGCGRGL+GRGC+GLGCG_{\mathrm{eq}}=\frac{G_RG_LG_C}{G_RG_L+G_RG_C+G_LG_C}

这个结果很符合直觉。三个串联元件展开时有内部节点;消去内部节点以后,对外就只剩一个等效二端口。

历史项也会被组合到端口上,形式变成:

Ihis,red=[Ieq,hisIeq,his]\mathbf I_{\mathrm{his,red}}=\begin{bmatrix}I_{\mathrm{eq,his}}\\-I_{\mathrm{eq,his}}\end{bmatrix}

其中:

Ieq,his=GR(GCIL,his+GLIC,his)GRGL+GRGC+GLGCI_{\mathrm{eq,his}}=\frac{G_R\left(G_CI_{L,\mathrm{his}}+G_LI_{C,\mathrm{his}}\right)}{G_RG_L+G_RG_C+G_LG_C}

于是外部节点方程就可以写成:

[IaIb]=[GeqGeqGeqGeq][uaub]+[Ieq,hisIeq,his]\begin{bmatrix}I_a\\I_b\end{bmatrix}=\begin{bmatrix}G_{\mathrm{eq}}&-G_{\mathrm{eq}}\\-G_{\mathrm{eq}}&G_{\mathrm{eq}}\end{bmatrix}\begin{bmatrix}u_a\\u_b\end{bmatrix}+\begin{bmatrix}I_{\mathrm{eq,his}}\\-I_{\mathrm{eq,his}}\end{bmatrix}

这就是“元件组合降阶”的具体样子:原来 R、L、C 三个元件展开后有a,c,d,ba,c,d,b四个节点;消去c,dc,d以后,对外只剩a,ba,b两个节点和一个等效二端支路。

消去不是免费午餐

节点消去的好处很明显:外部矩阵变小了。

原来这个支路如果完全展开,要把c,dc,d作为未知节点一起放进全局方程;消去以后,全局方程只需要处理a,ba,b。如果一个组件内部有几十、几百个内部节点,这种降阶对全局求解规模会很有帮助。

但代价也很明确:被消去的节点电压不再是主方程直接求出来的未知量。

在 RLC 例子里,消去后外部方程只能直接得到:

ua,ubu_a,\qquad u_b

它不会直接给出:

uc,udu_c,\qquad u_d

这意味着,如果你只保存 reduced equation,那么下面这些量也不会自动出现:

  • 电阻电压uR=uaucu_R=u_a-u_c
  • 电感电压uL=ucudu_L=u_c-u_d
  • 电容电压uC=udubu_C=u_d-u_b
  • 内部节点监测量;
  • 依赖内部节点电压的控制、保护或测量逻辑。

所以节点消去不是“什么信息都没少,只是矩阵变小了”。更准确地说,它是把内部节点从主求解器里拿掉了。外部端口行为可以保持等效,但内部变量需要额外恢复。

内部电压恢复公式

恢复公式其实前面已经推出来了:

Vk=WGkrVrWIhis,k\mathbf V_k=-WG_{kr}\mathbf V_r-W\mathbf I_{\mathrm{his},k}

对 RLC 例子来说,就是:

[ucud]=W([GR00GC][uaub]+[IL,hisIL,his+IC,his])\begin{bmatrix}u_c\\u_d\end{bmatrix}=-W\left(\begin{bmatrix}-G_R&0\\0&-G_C\end{bmatrix}\begin{bmatrix}u_a\\u_b\end{bmatrix}+\begin{bmatrix}I_{L,\mathrm{his}}\\-I_{L,\mathrm{his}}+I_{C,\mathrm{his}}\end{bmatrix}\right)

写成工程流程就是:

  • 第一步,用 reduced equation 求出保留节点ua,ubu_a,u_b
  • 第二步,用上一拍状态算出IL,hisI_{L,\mathrm{his}}IC,hisI_{C,\mathrm{his}}
  • 第三步,用恢复公式算出内部节点uc,udu_c,u_d
  • 第四步,再由节点电压差回算uR,uL,uCu_R,u_L,u_C和支路电流。

注意顺序很重要。恢复内部节点时,不能凭空猜uc,udu_c,u_d,也不能只看 reduced matrix。恢复公式需要用到原来参与消去的那部分矩阵,也就是GkkG_{kk}GkrG_{kr}和内部历史项Ihis,k\mathbf I_{\mathrm{his},k}

这也是很多程序里容易出错的地方:主方程已经降阶了,但监测量、保护逻辑或内部状态更新仍然需要内部电压。如果只做了消去,没有配套恢复,就会出现“端口电流对了,但内部电压不知道从哪里来”的问题。

小结

节点消去做的是一件非常朴素的事:把内部节点方程解出来,再代回外部节点方程。

标准形式是:

Gred=GrrGrkGkk1GkrG_{\mathrm{red}}=G_{rr}-G_{rk}G_{kk}^{-1}G_{kr}Ihis,red=Ihis,rGrkGkk1Ihis,k\mathbf I_{\mathrm{his,red}}=\mathbf I_{\mathrm{his},r}-G_{rk}G_{kk}^{-1}\mathbf I_{\mathrm{his},k}

对 RLC 串联支路来说,这一步会把展开的 R、L、C 三个元件组合成一个二端口等效支路。外部求解器只需要看a,ba,b两个端口,矩阵规模更小。

但这个降阶会损失内部节点的直接可见性。uc,udu_c,u_d被消去以后,如果后续还要元件电压、内部监测量或状态更新,就必须用:

Vk=Gkk1(GkrVr+Ihis,k)\mathbf V_k=-G_{kk}^{-1}\left(G_{kr}\mathbf V_r+\mathbf I_{\mathrm{his},k}\right)

把内部节点电压恢复出来。

所以,节点消去和电压恢复最好放在一起理解:消去负责让外部矩阵变小,恢复负责把被拿掉的内部信息找回来。


相关内容

Buy me a coffee~
RLC侠 支付宝支付宝
RLC侠 微信微信