Resistor mesh: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(One intermediate revision by one other user not shown)
Line 1,182:
{{out}}
<pre>R = 1.608991241729889</pre>
 
 
=={{header|JavaScript}}==
Kirchhoff's circuit laws on the resistor mesh are represented as a linear
equation system for the electric potential at each node of the grid.
The linear equation is then solved using the [https://en.wikipedia.org/wiki/Conjugate_gradient_method conjugate gradient method]:
<syntaxhighlight lang=JavaScript>
// Vector addition, scalar multiplication & dot product:
const add = (u, v) => {let i = u.length; while(i--) u[i] += v[i]; return u;};
const sub = (u, v) => {let i = u.length; while(i--) u[i] -= v[i]; return u;};
const mul = (a, u) => {let i = u.length; while(i--) u[i] *= a; return u;};
const dot = (u, v) => {let s = 0, i = u.length; while(i--) s += u[i]*v[i]; return s;};
 
const W = 10, H = 10, A = 11, B = 67;
 
function getAdjacent(node){ // Adjacency lists for square grid
let list = [], x = node % W, y = Math.floor(node / W);
if (x > 0) list.push(node - 1);
if (y > 0) list.push(node - W);
if (x < W - 1) list.push(node + 1);
if (y < H - 1) list.push(node + W);
return list;
}
 
function linOp(u){ // LHS of the linear equation
let v = new Float64Array(W * H);
for(let i = 0; i < v.length; i++){
if ( i === A || i === B ) {
v[i] = u[i];
continue;
}
// For each node other then A, B calculate the net current flow:
for(let j of getAdjacent(i)){
v[i] += (j === A || j === B) ? u[i] : u[i] - u[j];
}
}
return v;
}
 
function getRHS(phiA = 1, phiB = 0){ // RHS of the linear equation
let b = new Float64Array(W * H);
// Setting boundary conditions (electric potential at A and B):
b[A] = phiA;
b[B] = phiB;
for(let j of getAdjacent(A)) b[j] = phiA;
for(let j of getAdjacent(B)) b[j] = phiB;
return b;
}
 
function init(phiA = 1, phiB = 0){ // initialize unknown vector
let u = new Float64Array(W * H);
u[A] = phiA;
u[B] = phiB;
return u;
}
 
function solveLinearSystem(err = 1e-20){ // conjugate gradient solver
 
let b = getRHS();
let u = init();
let r = sub(linOp(u), b);
let p = r;
let e = dot(r,r);
 
while(true){
let Ap = linOp(p);
let alpha = e / dot(p, Ap);
u = sub(u, mul(alpha, p.slice()));
r = sub(linOp(u), b);
let e_new = dot(r,r);
let beta = e_new / e;
 
if(e_new < err) return u;
 
e = e_new;
p = add(r, mul(beta, p));
}
}
 
function getResistance(u){
let curr = 0;
for(let j of getAdjacent(A)) curr += u[A] - u[j];
return 1 / curr;
}
 
let phi = solveLinearSystem();
let res = getResistance(phi);
console.log(`R = ${res} Ohm`);
</syntaxhighlight>
{{out}}
<pre>R = 1.608991241730955 Ohm</pre>
 
=={{header|jq}}==
Line 2,276 ⟶ 2,367:
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="ecmascriptwren">class Node {
construct new(v, fixed) {
_v = v
9,476

edits