### Little bitty capacitor model

By Josh Adams.

Here’s some code I wrote to model capacitor circuits. It passes all my tests so far, and it’s such concise code it’s hard to imagine it breaking…

First, some unit tests. A refresher on the physics, full I’m sure of flaws and misconceptions: A capacitor is rated at a voltage and capacitance. A pair of capacitors in series acts like a single capacitor whose voltage=cap1.voltage+cap2.voltage, and whose capacitance^{-1}=(cap1.capacitance)^{-1}+(cap2.capacitance)^{-1}.

If it doesn’t make sense, skip ahead to the (better documented) class itself.

```
--- capacitor_test.rb ---
require 'test/unit'
require 'capacitor'
class CapacitorTest < Test::Unit::TestCase
DELTA_TOLERANCE = 5e-15
def setup
@cap = Capacitor.new(3.3e-8, 1_200) # A 0.03 uF capacitor that can handle 1.2kV
end
def test_series_capacitance
assert_equal 1.65e-8, (@cap*@cap).capacitance
end
def test_series_voltage
assert_equal 2_400, (@cap*@cap).voltage
end
def test_exponentiation
assert_equal Capacitor, (@cap**(2)).class
assert_equal 2_400, (@cap**2).voltage
end
def test_parallel_capacitance
assert_equal 6.6e-8, (@cap/@cap).capacitance
end
# For some reason I can't just assert_equal, because these values differ by some tiny amount. Hence the delta stuff.
def test_big_array_of_caps
@string = @cap**10 # string 10 capacitors up in series configuration
assert_in_delta 3.3e-9, @string.capacitance, DELTA_TOLERANCE
@grid = @string%8 # string 8 of the series-strings up in parallel configuration
assert_in_delta 2.64e-8, @grid.capacitance, DELTA_TOLERANCE
assert_in_delta 12_000, @grid.voltage, DELTA_TOLERANCE
end
end
```

Now, a bit of really basic abstract algebra. A boolean operation is an operation that takes a pair of elements of a set into a single element in the same set. So integer multiplication is a boolean operation because 2*3=6, where 2, 3, and 6 are all in the set Z (the integers). That is, *(2,3) maps to the integer 6.

Think of series wiring as a boolean operation. That is, a pair of capacitors maps to a capacitor with the same properties as the circuit itself. In this case, it makes perfect sense to just override a couple of boolean operators. It’s coming.

```
--- capacitor.rb ---
class Capacitor
attr_accessor :capacitance, :voltage
def initialize(cap, volt)
@capacitance = cap
@voltage = volt
end
```

Just setting some basic attributes. Capacitors have a capacitance and a voltage, right? I’m expecting SI standard base units, so capacitance should be in Farads and voltage in Volts. So to instantiate a .033uF (.033 microfarad, or 33 nanofarad, or 3.3e-8 farad) capacitor that can take 1,200 volts, we would say @cap1=Capacitor.new(3.3e-8,1_200).

Now, to the binary operations! I’m defining * and / as ‘wired in series’ and ‘wired in parallel,’ respectively. Similarly, ** is exponentiation in the expected sense (using the * operator), so (@cap1**3) represents three identical capacitors wired in series. Similarly, again, I’ve defined % as the inverse of that exponentiation, so (@cap1 % 3) would represent three of the same capacitor wired in parallel.

```
def *(cap2)
Capacitor.new(1/((1/(capacitance))+(1/cap2.capacitance)), voltage+cap2.voltage) # Here I've just embedded the appropriate behavior for
# series capacitor behavior into the operator
end
def /(cap2)
Capacitor.new((capacitance + cap2.capacitance), voltage)
end
def **(power)
c=self
(power-1).times{c=c*self}
c
end
def %(power)
c=self
(power-1).times{c=c/self}
c
end
end
```

That’s all the code it takes to end up with a really rich fake-DSL 🙂

I can now do something like this (haven’t tried it, but I don’t feel that I need to :))

```
(@cap * @cap * @cap * @cap) /
(@cap * @cap * @cap * @cap) /
(@cap * @cap * @cap * @cap) /
```

This would represent, in a very (imnshobbqhax) pleasant and visually graspable way, a circuit with three strings of capacitors wired in parallel, each string consisting of four capacitors wired in series. This could be represented more succinctly, though it’s less visually analogous to reality:

```
(@cap**4)%3
```

Hope someone enjoyed that. Let me know if you see a place I could improve this, of course. Also, I’d like to figure out a nice way to represent circuits more fully. I can see an easy way to model resistors similarly, and use a case statement to determine what the circuit’s representation would be for each operation…but that case statement would probably be wrapped up in the * and / methods of some CircuitElement class that handled all the various interconnects. I don’t know, let me know if this was a decent read…

There’s a Google Code project set up right here.

Filed under: Uncategorized | Leave a Comment

## No Responses Yet to “Little bitty capacitor model”