Commons Math is an Apache library which includes a variety of mathematical tools, including 1st and 2nd-order ODE solvers. In order to familiarize myself with the ODE solvers, I wrote a simple program to solve an RC charging circuit.
The circuit has these parameters:
- R (ohms), the resistance of the resistor
- C (farads), the capacitance of the capacitor
- V (volts), the voltage of the supply current
Differential equation solvers need initial conditions, so I've supplied the voltage across the capacitor as zero. That is, the capacitor starts uncharged.
Commons Math requires that all equations are provided in the form
y' = f(y, t)
That is, the equation must provide the differential in terms of time, and the current state: y. Note that both y' and y can be vectors.
In my case, the equation I've supplied is:
Vc' = - (Vc-Vin)/RC;
- Vc' is the derivative with respect to time of the capacitor charge
- Vc is the current capacitor charge
- Vin is the supply voltage
This equation is coded as an implementation of FirstOrderDifferentialEquations. Note that I could have supplied an multiple equations using this interface, and I could have done something more complex using SecondOrderDifferentialEquations. My implementation is here.
Once I've defined equations, there are multiple implementations of ODE solvers. For simplicity I chose ClassicalRungeKuttaIntegrator, however any of the implementations of AdaptiveStepsizeIntegrator might be faster. My code to invoke the integrator with a step size of 1e-6 seconds is here.
The output of the test using
- R = 100KOhm
- V = 12V
- C = 10 nF
- Vc(0) = 0 V
- step size 1e-6 seconds
- T (0) = 0 seconds
- T (N) = .1 seconds
Starts like this:
1.0E-6,0.0011999400019999497 2.0E-6,0.0023997600159991993 3.0E-6,0.0035994600539959497 4.0E-6,0.0047990401279872 4.9999999999999996E-6,0.005998500249968752 5.999999999999999E-6,0.007197840431935207 6.999999999999999E-6,0.008397060685879965 8.0E-6,0.009596161023795232 9.0E-6,0.010795141457672009 1.0E-5,0.0119940019995001 1.1000000000000001E-5,0.01319274266126811 1.2000000000000002E-5,0.014391363454963448 1.3000000000000003E-5,0.01558986439257232 1.4000000000000003E-5,0.016788245486079736 1.5000000000000004E-5,0.017986506747469506 1.6000000000000003E-5,0.019184648188724243 1.7000000000000003E-5,0.020382669821825364 1.8000000000000004E-5,0.021580571658753083 1.9000000000000004E-5,0.02277835371148642 2.0000000000000005E-5,0.02397601599200319 2.1000000000000006E-5,0.025173558512280026
and ends like this:
0.09998900000007933,11.99945460123407 0.09999000000007933,11.99945465577122 0.09999100000007934,11.999454710302917 0.09999200000007934,11.99945476482916 0.09999300000007934,11.999454819349952 0.09999400000007934,11.999454873865291 0.09999500000007934,11.99945492837518 0.09999600000007934,11.999454982879616 0.09999700000007934,11.999455037378603 0.09999800000007934,11.99945509187214 0.09999900000007934,11.999455146360228
Pretty much exactly what you'd expect; the capacitor charges to ~12V, exponentially.