基本思想很简单。您可以安排一个表示系统中“节点”或顶点的矩阵()。这些节点中的每个节点都有一个与之关联的标量值“电压”,可以随着算法的进行而更改或更新。也将有两个节点的电压无法更改。我们将在此处应用某种“电池”,因此这两个节点代表该电池的两端。V
另外,另外两个矩阵(和)表示系统中的水平和垂直边缘。我猜这些是您的抵抗值。我不确定您打算如何填写这些内容。但这就是你的问题。此技术假定您也可以填充这些矩阵。RvRh
根据您使用的计算机语言,您是否可以使用负索引。没关系 这只是记住您所面临的问题。
假定长度分为部分,而“长度”分为部分。然后,您将需要构造一个带有个顶点的矩阵,用于标量电压值。(或更大。)您还需要另外两个矩阵,这些矩阵之间的垂直边为垂直边为。LNLANA(NL+1)⋅(NA+1)NA⋅(NL+1)NL⋅(NA+1)
现在。用初始化所有顶点。选择左侧的一个顶点(最好是在中间),并将其记为值,该值永远不能更改。为此使用任何想要的方法。选择右侧的一个顶点(最好是在中间),并将其值更改为,同时再次注意,其值永远不可更改。在这里起作用的一种技术是简单地使其正常变化,然后在每个步骤中替换该值。但是,只要实现了,就如何实现它并不重要。0V0V1V
(出于效率方面的考虑,还有其他技术。但是在这里可能不值得一试。)
现在是该算法,有时称为棋盘格或红黑算法。遍历节点电压矩阵,处理两个索引为偶数的每个节点,执行以下简单分配:i+j
Vi,j=Rhi,j−1⋅Rhi,j⋅(Vi−1,j⋅Rvi,j+Vi+1,j⋅Rvi−1,j)Rhi,j−1⋅Rhi,j⋅(Rvi,j+Rvi−1,j)+Rvi−1,j⋅Rvi,j(Rhi,j+Rhi,j−1)+Rvi−1,j⋅Rvi,j⋅(Vi,j−1⋅Rhi,j+Vi,j+1⋅Rhi,j−1)Rhi,j−1⋅Rhi,j⋅(Rvi,j+Rvi−1,j)+Rvi−1,j⋅Rvi,j(Rhi,j+Rhi,j−1)
上面的等式无非是计算一个中央节点的电压,该中央节点有四个连接到其上的电阻器,其中四个电阻器另一端的电压是已知的。然后根据上式计算中心节点电压。由于每个项的除数都相同,因此您只需计算分子的总和,然后除以分母一次即可。
这将更新总和为偶数的所有节点。现在,您对总和为奇数的所有节点执行相同的过程。完成这两个步骤后,您就完成了一个周期。i+ji+j
如有必要,请重置特殊的两个节点(如前所述,用于和用于。)或者,如果保护了这两个节点,则无需重置它们。0V1V
您已准备好进行下一个周期。尽可能多地执行这些循环,以使整体状态稳定下来(并且会如此)。
当您停止该过程时,可以通过选择查看左侧受保护节点周围的节点或查看右侧受保护节点周围的节点来轻松计算阻力。(最好使矩阵足够大(在所有方向上都乘以1),这样您实际上将有四个围绕任一选择的节点。)周围节点与特殊节点之间的电压差除以它们之间边缘的电阻告诉您当前离开/进入您的特殊节点。由于这是一个“电池”节点,因此该电流必须是所有电流。由于电压为,按照定义,将1除以这四个电流的总和即可得出总电阻。1V
我盯着我写的那些总共有67条代码的代码,上面有很多注释。因此写起来并不难。
这个想法的“简短摘要”是,您使用电池,然后观察电压在系统中的分布情况。一旦电压稳定下来(您的标准),您所要做的就是查看流入或流出一个电池端子或另一个电池端子的电流。由于明显的原因,它们都应为相同的当前值(在某些数值范围内)。1V
为什么必须将系统分成i + j =偶数和i + j =奇数?
假设您计算。这引用了围绕的节点。没关系。假设您接下来计算。请注意,在参数列表中是您刚刚为计算的值吗?这会“弄脏”很多东西。没声音 取而代之的是,每个奇/偶周期应该“似乎”出现在同一时刻。因此,下一个计算应为因为该函数的输入是在此期间更改的节点V5,5=f(V4,5,V6,5,V5,4,V5,6)V5,5V5,6=f(V4,6,V6,6,V5,5,V5,7)V5,5V5,7=f(V4,7,V6,7,V5,6,V5,8)这一步。然后,您可以四处旋转并计算替代方案,避免弄脏,但现在可以更新替代方案。您确实必须采用这种方式。
另外,偶数和奇数步长的公式是否相同?
是的,是一样的。
是否可以使用某种线性系统Ax = b(其中A是线性算子,b提供边界条件)一步一步解决所有问题?看上去,它似乎与求解偏微分方程的有限差分方法类似。
有连接。我认为这被称为“无矩阵”实现。
这是一个例子。将以下电阻值集放置到LTSpice中进行仿真:
我让它简短而简单。如您所见,来自电源的近似计算电流为。(Spice计算的实际值为。)1V30.225mA30.224552mA
我运行了以下VB.NET程序:
Module GEOGRID
Const NL As Integer = 2
Const NA As Integer = 2
Const INF As Double = 1.0E+32
Sub Main()
Static Rh As Double(,) = New Double(NL + 2, NA + 1) {
{INF, INF, INF, INF},
{INF, 5, 21, INF},
{INF, 76, 10, INF},
{INF, 32, 22, INF},
{INF, INF, INF, INF}}
Static Rv As Double(,) = New Double(NA + 1, NL + 2) {
{INF, INF, INF, INF, INF},
{INF, 61, 50, 16, INF},
{INF, 56, 45, 18, INF},
{INF, INF, INF, INF, INF}}
Dim V As Double(,) = New Double(NL + 2, NA + 2) {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}}
Dim PDE As Func(Of Integer, Integer, Double) = Function(ByVal i As Integer, ByVal j As Integer) (
Rh(i, j - 1) * Rh(i, j) * (V(i - 1, j) * Rv(i, j) + V(i + 1, j) * Rv(i - 1, j)) +
Rv(i - 1, j) * Rv(i, j) * (V(i, j - 1) * Rh(i, j) + V(i, j + 1) * Rh(i, j - 1))
) / (
Rh(i, j - 1) * Rh(i, j) * (Rv(i, j) + Rv(i - 1, j)) +
Rv(i - 1, j) * Rv(i, j) * (Rh(i, j) + Rh(i, j - 1))
)
Dim IV As Func(Of Integer, Integer, Double) = Function(ByVal i As Integer, ByVal j As Integer) 0 +
(V(i, j) - V(i - 1, j)) / Rv(i - 1, j) + (V(i, j) - V(i + 1, j)) / Rv(i, j) +
(V(i, j) - V(i, j - 1)) / Rh(i, j - 1) + (V(i, j) - V(i, j + 1)) / Rh(i, j)
Dim idx As Integer = NA \ 2 + 1
Dim jdx1 As Integer = NL + 1
Dim jdx2 As Integer = 1
For x As Integer = 1 To 1000
For k As Integer = 0 To (NA + 1) * (NL + 1) - 1 Step 2
Dim i As Integer = k \ (NL + 1)
Dim j As Integer = k - i * (NL + 1) + 1
i += 1
If Not (i = idx AndAlso (j = jdx1 OrElse j = jdx2)) Then V(i, j) = PDE(i, j)
Next
For k As Integer = 1 To (NA + 1) * (NL + 1) - 1 Step 2
Dim i As Integer = k \ (NL + 1)
Dim j As Integer = k - i * (NL + 1) + 1
i += 1
If Not (i = idx AndAlso (j = jdx1 OrElse j = jdx2)) Then V(i, j) = PDE(i, j)
Next
Next
Console.WriteLine("R = " & (1.0 / IV(idx, jdx1)).ToString)
Console.WriteLine("R = " & (-1.0 / IV(idx, jdx2)).ToString)
End Sub
End Module
打印出以下结果:。这是正确的答案。R=33.0856844038614Ω
上面的程序显示了一种设置垂直和水平电阻以及电压矩阵的方法,从而简化了一些针对不存在的节点和/或电阻值的测试。这样,虽然确实需要更多的数组元素,但是代码更简洁一些。(我只是简单地将额外的电阻值设置为无限大。)只需将我如何设置阵列与原理图的布局方式进行比较,我想您将能够得出所有准确的结果。详细信息在这里。
当然,我也侵入了电阻和节点值,而没有以任何方式使它成为读取值表的通用程序。但是,这种通用性很容易添加。这段代码应该使我编写的所有内容完全明确。
请注意,我也只运行了循环1000种类型,在循环内交替显示红色和黑色。我刚选了一个号码。为了使这个目的更通用,您可能希望采用另一种方法来确定要执行的迭代次数。xx
最后一点。只是为了证明您可以使用固定电压节点的电流来计算电阻,我使用了两行以打印出这两个值:一个是从端计算出来的,而另一根是从一侧。无论哪种方式,您都应该看到相同的数字。0V1V
(好的。还有最后一点。这将更好地针对F#或针对大规模并行计算系统的任何体面的编译器。“ red”或“ black”中的每个计算都可以并行执行;彼此完全独立。 F#非常简单。因此用F#编码,您可以在所有可用的内核上运行此代码而无需做任何特殊的事情。它可以正常工作。请注意,如果您以某种方式收集了大量数据并且可能想要充分利用多核系统的优势。)
结束提示:
从KCL推导非常简单。将四个电阻器放置为以下布置:
模拟该电路 –使用CircuitLab创建的原理图
申请KCL:
VR1+VR2+VR3+VR4V=V1R1+V2R2+V3R3+V4R4∴=(V1R1+V2R2+V3R3+V4R4)(R1∣∣R2∣∣R3∣∣R4)
一些代数运算会得到我在代码中使用的结果。