- millman-theorem.py
- millman-theorem.py
####################################################################################################
#r# ===================
#r# Millman's theorem
#r# ===================
#r#
#r# Millman's theorem is a method to compute the voltage of a node in such circuits:
#f# circuit_macros('millman-theorem.m4')
#r# The voltage at node A is:
#r#
#r# .. math::
#r#
#r# V_A = \frac{\sum \frac{V_i}{R_i}}{\sum \frac{1}{R_i}}
#r#
#r# We can extend this theorem to branches with current sources:
#r#
#r# .. math::
#r#
#r# V_A = \frac{\sum \frac{V_i}{R_i} + \sum I_k}{\sum \frac{1}{R_i}}
#r#
#r# Note voltage sources can be null and resistances in current's branches don't change the denominator.
#f# circuit_macros('millman-theorem-with-current-source.m4')
####################################################################################################
import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()
####################################################################################################
import numpy as np
####################################################################################################
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *
####################################################################################################
circuit = Circuit("Millman's theorem")
number_of_branches = 3
for i in range(1, number_of_branches +1):
circuit.V('input%u' % i, i, circuit.gnd, i@u_V)
circuit.R(i, i, 'A', i@u_kΩ)
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.operating_point()
node_A = analysis.A
print('Node {}: {:5.2f} V'.format(str(node_A), float(node_A)))
#o#
branch_voltages = np.arange(1, number_of_branches +1)
branch_resistances = branch_voltages * float(kilo(1))
conductances = 1 / branch_resistances
voltage_A = np.sum(branch_voltages * conductances) / np.sum(conductances)
print('V(A) = {:5.2f} V'.format(voltage_A))
#o#
# with current sources
for i in range(1, number_of_branches +1):
ii = number_of_branches + i
circuit.I('input%u' % i, circuit.gnd, ii, 100*i@u_uA)
circuit.R(ii, ii, 'A', i@u_kΩ)
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.operating_point()
node_A = analysis.A
print('Node {}: {:5.2f} V'.format(str(node_A), float(node_A)))
#o#
branch_currents = np.arange(1, number_of_branches +1) * float(micro(100))
voltage_A += np.sum(branch_currents) / np.sum(conductances)
print('V(A) = {:5.2f} V'.format(voltage_A))
#o#
8.8.1. Millman’s theorem¶
Millman’s theorem is a method to compute the voltage of a node in such circuits:
The voltage at node A is:
\[V_A = \frac{\sum \frac{V_i}{R_i}}{\sum \frac{1}{R_i}}\]
We can extend this theorem to branches with current sources:
\[V_A = \frac{\sum \frac{V_i}{R_i} + \sum I_k}{\sum \frac{1}{R_i}}\]
Note voltage sources can be null and resistances in current’s branches don’t change the denominator.
import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()
import numpy as np
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *
circuit = Circuit("Millman's theorem")
number_of_branches = 3
for i in range(1, number_of_branches +1):
circuit.V('input%u' % i, i, circuit.gnd, i@u_V)
circuit.R(i, i, 'A', i@u_kΩ)
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.operating_point()
node_A = analysis.A
print('Node {}: {:5.2f} V'.format(str(node_A), float(node_A)))
[1;32m2019-03-10 18:51:07,562[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.531 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,563[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.531 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,564[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.531 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,565[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.531 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,566[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.531 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,566[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.555 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,567[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.676 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,568[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.836 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,568[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.898 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,569[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.930 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,570[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.980 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,570[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 823.980 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,574[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 824.238 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,576[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 824.238 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,577[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 824.238 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,585[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 824.441 MB, limit = 797.078 MB
Node a: 1.64 V
branch_voltages = np.arange(1, number_of_branches +1)
branch_resistances = branch_voltages * float(kilo(1))
conductances = 1 / branch_resistances
voltage_A = np.sum(branch_voltages * conductances) / np.sum(conductances)
print('V(A) = {:5.2f} V'.format(voltage_A))
V(A) = 1.64 V
# with current sources
for i in range(1, number_of_branches +1):
ii = number_of_branches + i
circuit.I('input%u' % i, circuit.gnd, ii, 100*i@u_uA)
circuit.R(ii, ii, 'A', i@u_kΩ)
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.operating_point()
node_A = analysis.A
print('Node {}: {:5.2f} V'.format(str(node_A), float(node_A)))
[1;32m2019-03-10 18:51:07,615[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 824.820 MB, limit = 797.078 MB
[1;32m2019-03-10 18:51:07,618[0m - [1;34mPySpice.Spice.NgSpice.Shared.NgSpiceShared._send_char[0m - [1;31mERROR[0m - Warning - approaching max data size: current size = 824.820 MB, limit = 797.078 MB
Node a: 1.96 V
branch_currents = np.arange(1, number_of_branches +1) * float(micro(100))
voltage_A += np.sum(branch_currents) / np.sum(conductances)
print('V(A) = {:5.2f} V'.format(voltage_A))
V(A) = 1.96 V