Capacitor Discharge with Exponential Functions¶
Try it live on Compiler Explorer
Overview¶
This example demonstrates using mathematical functions with dimensional analysis by modeling an RC circuit's capacitor discharge. It showcases:
- How exponential functions work with dimensionless quantities
- Automatic SI prefix selection for readable output across wide value ranges
- Dimensional analysis ensuring correct physics
Circuit Model¶
The example simulates an RC discharge circuit where a charged capacitor discharges through a resistor, following the exponential decay equation:
- Parameters:
- Capacitance: 0.47 μF
- Initial voltage: 5.0 V
- Resistance: 4.7 kΩ
- Time constant: τ = RC = 2.209 ms
- Expected behavior:
- At t = 0: V = 5.0 V (initial)
- At t = τ: V ≈ 1.84 V (37% of initial)
- At t = 5τ: V ≈ 0.034 V (< 1%)
Key Concepts¶
Dimensional Analysis in Exponential Functions¶
The library provides exp() that works with dimensionless quantities:
{
using namespace mp_units;
using namespace mp_units::si::unit_symbols;
constexpr auto CC = isq::capacitance(0.47 * uF);
constexpr auto V0 = isq::voltage(5.0 * V);
constexpr auto RR = isq::resistance(4.7 * si::kilo<si::ohm>);
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
std::cout.precision(3);
std::cout << "Capacitor time curve example for the following parameters:\n";
std::cout << "Capacitance: " << CC << "\n";
std::cout << "Initial Voltage: " << V0 << "\n";
std::cout << "Resistance: " << RR << "\n";
std::cout << "Time curve:\n";
for (auto tt = 0 * ms; tt <= 50 * ms; ++tt) {
const QuantityOf<isq::voltage> auto Vt = V0 * exp(-tt / (RR * CC));
std::cout << "- at " << tt << " voltage is ";
si::invoke_with_prefixed([](auto q) { std::cout << q; }, Vt, V);
std::cout << "\n";
}
}
How it works:
- RC time constant:
RR * CCresults in a time quantity (Ω·F = s) - Dimensionless ratio:
tt / (RR * CC)divides time by time → dimensionless - Exponential function:
exp()accepts the dimensionless quantity directly - Dimension restoration: Multiplying by
V0gives the result being a voltage quantity
The library automatically verifies dimensional correctness at compile time, preventing common physics errors.
Automatic SI Prefix Selection¶
Rather than manually selecting output units, the example uses invoke_with_prefixed():
const QuantityOf<isq::voltage> auto Vt = V0 * exp(-tt / (RR * CC));
std::cout << "- at " << tt << " voltage is ";
si::invoke_with_prefixed([](auto q) { std::cout << q; }, Vt, V);
This function automatically:
- Calculates the appropriate SI prefix (V, mV, μV, nV, pV, etc.)
- Ensures values stay in readable range (typically [1.0, 1000) for engineering mode)
- Handles the output formatting in a single call
The lambda receives the quantity scaled to the optimal prefix, ready for output.
Sample Output¶
Capacitor time curve example for the following parameters:
Capacitance: 0.470 µF
Initial Voltage: 5.000 V
Resistance: 4.700 kΩ
Time curve:
- at 0 ms voltage is 5.000 V
- at 1 ms voltage is 3.180 V
- at 2 ms voltage is 2.022 V
- at 3 ms voltage is 1.286 V
- at 4 ms voltage is 817.638 mV ← Transition to millivolts
- at 5 ms voltage is 519.946 mV
...
- at 15 ms voltage is 5.623 mV
- at 18 ms voltage is 1.446 mV
- at 19 ms voltage is 919.446 µV ← Transition to microvolts
- at 20 ms voltage is 584.688 µV
...
- at 30 ms voltage is 6.323 µV
- at 34 ms voltage is 1.034 µV
- at 35 ms voltage is 657.491 nV ← Transition to nanovolts
...
- at 45 ms voltage is 7.110 nV
- at 49 ms voltage is 1.163 nV
- at 50 ms voltage is 739.358 pV ← Transition to picovolts
The output demonstrates seamless transitions between SI prefixes (V → mV → μV → nV → pV) as the voltage decays over 9 orders of magnitude, keeping values in a readable range throughout.
Why This Matters¶
Compile-Time Dimensional Safety¶
The library ensures dimensional correctness at compile time:
// ✓ Correct: time/time is dimensionless
QuantityOf<dimensionless> auto dimensionless_arg = -tt / (RR * CC);
// ✗ Won't compile: can't take exp of a dimensional quantity
// auto wrong = exp(-tt); // Error: exp requires dimensionless!
This prevents common physics/engineering errors where equations are dimensionally invalid.
Practical Applications¶
This exponential decay pattern applies across many domains:
- Electrical: RC/RL circuits, signal decay, filter response
- Thermal: Newton's law of cooling, heat dissipation
- Mechanical: Damped oscillations, friction
- Chemistry: First-order reactions, radioactive decay
- Biology: Drug metabolism, population decay
Output Readability¶
Instead of choosing fixed units (forcing users to read 0.000005 V or 5000000 nV),
automatic prefix selection maintains readability across 9+ orders of magnitude.