It is used in a broad range of applications including performing scientific calculations thanks to the SciPy libraries.
This blog entry links to a pair of Google Colaboratory documents. Colaboratory documents are Python Jupyter Notebooks hosted in a Google Drive account that run the code in virtual machines owned by Google.
That way you don't need to have Python installed to try or modify the proposed code.
Solving circuits with SymPySymPy is one of the SciPy libraries. It enables you to perform symbolic calculations. This can come handy to solve electrical circuits like the one below:
You start defining symbols for the circuit. We need symbols for the component values Vs, R1, R2 and Is and for the solution Vo.
As we will solve the circuit using the nodal method that applies current equations in all nodes except the ground one, we also need symbols for the nodal voltages V1 and V2.
Also, using the full nodal method requires as to add a symbol, like iVs for the current in the source voltages.
# Create the circuit symbols
Vs,iVs,R1,R2,Is,Vo, V1, V2 = sympy.symbols('Vs,iVs,R1,R2,Is,Vo,V1,V2')
Now we define the equations of nodes 1 and 2. To do that, we initizalize an empty list of equations and add the two equations to this list. Using the nodal method, we apply the Kirchhoff KCL law on each node:
# Create an empty list of equations
equations = 
# Nodal equations
equations.append(iVs-(V1-V2)/R1) # Node 1
equations.append(Is-(V2-V1)/R1-V2/R2) # Node 2
In SymPy it is assumed that all equations are equal to zero.
In the nodal method we also need to add an equation for each voltage source that relates it to the node voltages. In SymPy, Eq means equal, so, Eq(Vs,V1) means Vs = V1.
# Voltage source equations
The final equation is the one that contains the result we want to obtain for the circuit:
# Measurement equations
Now we have a full set of equations:
iVs - (V1 - V2)/R1 Is - V2/R2 - (-V1 + V2)/R1 Eq(Vs, V1) Eq(Vo, V2)
Those equations enables us to obtain Vo but a smaller set of equation will also work. In particular, as the first equation contains an unknown iVs that is not found in any other equation, we can eliminate this equation if the only unknown we care for is Vo. We don't need, however, to know that to solve the circuit.
In these equations, some variables are unknowns, we make a list of them:
unknowns = [V1,V2,iVs,Vo]
Then we can solve the circuit using the solve function of the SymPy library:
# Solve the circuit
solution = sympy.solve(equations,unknowns)
That will yield the solutions for the unknowns:
V1 = Vs V2 = R2*(Is*R1 + Vs)/(R1 + R2) iVs = (-Is*R2 + Vs)/(R1 + R2) Vo = R2*(Is*R1 + Vs)/(R1 + R2)
If you want to see more details, more circuit solutions or you want to test te code yourself, open this colaboratory document.
Automating the solutionAs you can see we have followed a recipe for solving the circuit. That means that it can be automated. The circuit Python module, just does that: Solves a circuit using the nodal method recipe.
As we remember the circuit is:
# Circuit 1 definiton
c1 = circuit.circuit() # New circuit
c1.addV('Vs',1,0,5) # Vs between 1 and GND with 5 V value
c1.addR('R1',1,2,1000) # R1 between 1 and 2 with 1000 Ohm value
c1.addR('R2',2,0,1000) # R2 between 2 and GND with 1000 Ohm value
c1.addI('Is',2,0,0.01) # Is going from GND to 2 with 10 mA value
c1.addVM('Vo',2,0) # Measurement Vo between 2 and GND
Then we can obtain the symbolic solution for Vo:
# Symbolic solution
print('Vo =',c1.solution['Vo'],' (Symbolic)')
Vo = R2*(Is*R1 + Vs)/(R1 + R2) (Symbolic)
Note that this is the very same solution we obtained previously without using the SymPy module.
Also, as we have indicated the component values, we can also obtain the numerical solution:
# Numeric solution
print('Vo =',c1.particular['Vo'],'V (Particular)')
Vo = 7.5 V (Particular)
If you want to see more about the circuit module, see other solutions or use your own code, open this colaboratory document.