L'idea di base è abbastanza semplice. Disponi una matrice ( ) che rappresenta "nodi" o vertici nel tuo sistema. A ciascuno di questi nodi è associata una "tensione" a valori scalari che può essere modificata o aggiornata man mano che l'algoritmo procede. Ci saranno anche due nodi la cui tensione non può essere modificata. Qui applicheremo una sorta di "batteria", quindi quei due nodi rappresentano le due estremità di questa batteria.V
Separatamente, altre due matrici ( eRv ) rappresentano i bordi nel sistema, orizzontale e verticale. Questi sono i tuoi valori di resistenza, immagino. Non sono sicuro di come intendi compilarli. Ma questo è il tuo problema. Questa tecnica presuppone che tu sia in grado di popolare anche queste matrici.Rh
A seconda del linguaggio utilizzato, è possibile o meno utilizzare indici negativi. Non importa È solo una questione di tenere a mente ciò che devi affrontare.
Supponiamo che la lunghezza sia divisa in N sezioni L e che la "lunghezza" A sia divisa in sezioni N A. Quindi dovrai costruire una matrice con ( N L + 1 ) ⋅ ( N A + 1 ) vertici per i valori di tensione scalare. (o più grande) Avrai anche bisogno di quelle altre due matrici con bordi verticali N A ⋅ ( N L + 1 ) e N L ⋅ ( N A + 1LNLANA(NL+1)⋅(NA+1)NA⋅(NL+1) bordi orizzontali tra quei vertici.NL⋅(NA+1)
Adesso. Inizializza tutti i vertici con . Scegli uno dei vertici a sinistra (al centro, preferibilmente) e annotalo come 00VValore V che NON può mai cambiare. Usa qualunque metodo tu voglia per questo. Scegli uno dei vertici a destra (al centro, preferibilmente) e cambia il suo valore in 10V , pur prendendo di nuovo atto che il suo valore NON può mai cambiare. Una tecnica che funziona qui è semplicemente lasciarlo cambiare normalmente ma poi sostituire il valore ogni singolo passaggio. Ma non importa come raggiungi questo, purché lo raggiungi.1V
(Esistono altre tecniche per motivi di efficienza. Ma probabilmente non vale la pena preoccuparsene qui.)
Ora per l'algoritmo, che a volte viene chiamato scacchiera o algoritmo rosso-nero . Muovendosi attraverso la matrice di tensione del nodo, elaborare ciascun nodo in cui la somma dei due indici, è pari, eseguendo la seguente semplice assegnazione: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)
L'equazione di cui sopra non è altro che calcolare la tensione di un nodo centrale avente quattro resistori collegati ad esso, dove sono note le tensioni alle altre estremità dei quattro resistori. La tensione del nodo centrale viene quindi calcolata dall'equazione sopra. Poiché il divisore è lo stesso per ogni termine, puoi semplicemente calcolare la somma dei numeratori e quindi dividere una volta per il denominatore.
Ciò aggiornerà tutti i nodi in cui la somma è pari. Ora esegui la stessa procedura per tutti i nodi in cui la somma i + ji+ji+j è dispari. Una volta eseguiti entrambi questi passaggi, hai completato un ciclo.
Se necessario, ripristinare i due nodi speciali (per e per 10V come discusso in precedenza.) Oppure, se hai protetto questi due nodi, non è necessario ripristinarli.1V
Sei pronto per il ciclo successivo. Esegui questi cicli tutte le volte che ritieni necessario affinché lo stato generale si stabilizzi (e lo farà).
Quando interrompi il processo, puoi facilmente calcolare la resistenza scegliendo di esaminare i nodi che circondano il nodo protetto sul lato sinistro oppure i nodi che circondano il nodo protetto sul lato destro. (Potrebbe essere una buona idea rendere la tua matrice appena più grande [di 1 in tutte le direzioni] in modo da avere effettivamente quattro nodi che circondano entrambe le scelte.) La differenza di tensione tra i nodi circostanti e il nodo speciale, divisa per la resistenza nei bordi tra loro ti dice l'attuale partenza / entrata nel tuo nodo speciale. Poiché si tratta di un nodo "batteria", questa corrente deve essere TUTTA la corrente. Poiché la tensione è 1V
Sto fissando un codice che ho scritto che totalizza, con molti commenti, solo 67 righe. Quindi NON è difficile da scrivere.
1V
Perché è necessario separare il sistema in i + j = pari e i + j = dispari?
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)perché nessuno degli input per la funzione sono nodi che sono stati modificati durante questo passaggio. Quindi ti muovi e calcoli gli alternati, evitando le sbavature ma ora aggiornando gli alternati. Devi davvero farlo in questo modo.
Inoltre, la formula è identica per i passaggi pari e dispari?
Sì, è lo stesso.
Tutto può essere risolto in un solo passaggio usando una sorta di sistema lineare Ax = b dove A è un operatore lineare e b fornisce le condizioni al contorno? Guardandolo, sembra in qualche modo analogo ai metodi a differenza finita per risolvere equazioni differenziali parziali.
C'è una connessione Penso che sia chiamata un'implementazione 'senza matrice'.
Ecco un esempio Il seguente set di valori di resistenza è stato inserito in LTSpice per la simulazione:
1V30.225mA30.224552mA
Ho eseguito il seguente programma 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Ω
Il programma sopra mostra un modo per impostare i resistori, verticali e orizzontali, nonché la matrice di tensione, in modo da semplificare alcuni dei test per nodi inesistenti e / o valori di resistori. Il codice è un po 'più pulito, in questo modo, anche se richiede più elementi dell'array. (Ho semplicemente reso infiniti i valori dei resistori extra.) Basta confrontare il modo in cui ho impostato gli array con il modo in cui è stato disposto lo schema, e penso che sarai in grado di elaborare esattamente dettagli qui.
Ho anche hackerato i resistori e i valori dei nodi, ovviamente, senza renderlo in alcun modo un programma generico per la lettura di una tabella di valori. Ma questa generalità è abbastanza facile da aggiungere. E questo codice dovrebbe rendere tutto inequivocabile tutto ciò che ho scritto.
xX
0V1V
(Va bene. Un'altra nota finale. Questo sarebbe molto più mirato su F # o su qualsiasi compilatore decente destinato a un sistema di elaborazione massicciamente parallelo. Ogni calcolo in "rosso" o "nero" può essere eseguito in parallelo, completamente indipendentemente l'uno dall'altro. F # lo rende banale. Così codificato in F #, potresti eseguirlo su tutti i tuoi core disponibili senza nulla di speciale da fare. Funziona. Solo una nota nel caso in cui stai raccogliendo MOLTI dati in qualche modo e potresti voler prendere pieno vantaggio di un sistema multi-core.)
NOTA FINE:
La derivazione è piuttosto semplice da KCL. Posizionare quattro resistori nella seguente disposizione:
simula questo circuito - Schema creato usando CircuitLab
Applica KCL:
VR1+ VR2+ VR3+ VR4V= V1R1+ V2R2+ V3R3+ V4R4∴= ( V1R1+ V2R2+ V3R3+V4R4) ( R1∣ ∣ R2∣ ∣ R3∣ ∣ R4)
Alcuni che giocano con l'algebra ottengono il risultato che ho usato nel codice.