In [2]:
    
# Configure Jupyter so figures appear in the notebook
%matplotlib inline
# Configure Jupyter to display the assigned value after an assignment
%config InteractiveShell.ast_node_interactivity='last_expr_or_assign'
# import functions from the modsim.py module
from modsim import *
    
In [3]:
    
with units_off():
    for i, name in enumerate(dir(UNITS)):
        unit = getattr(UNITS, name)
        try:
            res = 1*unit - 1
            if res == 0:
                print(name, 1*unit - 1)
        except TypeError:
            pass
        if i > 10000:
            break
    
    
In [5]:
    
with units_off():
    print(2 * UNITS.farad - 1)
    
    
In [6]:
    
with units_off():
    print(2 * UNITS.volt - 1)
    
    
In [7]:
    
with units_off():
    print(2 * UNITS.newton - 1)
    
    
In [10]:
    
mN = UNITS.gram * UNITS.meter / UNITS.second**2
    
    Out[10]:
In [11]:
    
with units_off():
    print(2 * mN - 1)
    
    
Now I'll create a Params object to contain the quantities we need.  Using a Params object is convenient for grouping the system parameters in a way that's easy to read (and double-check).
In [8]:
    
params = Params(
    R1 = 1e6, # ohm
    C1 = 1e-9, # farad
    A = 5, # volt
    f = 1000, # Hz 
)
    
    Out[8]:
Now we can pass the Params object make_system which computes some additional parameters and defines init.
make_system uses the given radius to compute area and the given v_term to compute the drag coefficient C_d.
In [9]:
    
def make_system(params):
    """Makes a System object for the given conditions.
    
    params: Params object
    
    returns: System object
    """
    unpack(params)
    
    init = State(V_out = 0)
    omega = 2 * np.pi * f
    tau = R1 * C1
    cutoff = 1 / R1 / C1
    t_end = 3 / f
    
    return System(params, init=init, t_end=t_end,
                  omega=omega, cutoff=cutoff)
    
Let's make a System
In [10]:
    
system = make_system(params)
    
    Out[10]:
Here's the slope function,
In [11]:
    
def slope_func(state, t, system):
    """Compute derivatives of the state.
    
    state: position, velocity
    t: time
    system: System object
    
    returns: derivatives of y and v
    """
    V_out, = state
    unpack(system)
    
    V_in = A * np.cos(omega * t)
    
    V_R1 = V_in - V_out
    
    I_R1 = V_R1 / R1    
    I_C1 = I_R1
    dV_out = I_C1 / C1
    
    return dV_out
    
As always, let's test the slope function with the initial conditions.
In [12]:
    
slope_func(system.init, 0, system)
    
    Out[12]:
And then run the simulation.
In [13]:
    
ts = linspace(0, system.t_end, 301)
results, details = run_ode_solver(system, slope_func, t_eval=ts)
details
    
    
    Out[13]:
Here are the results.
In [14]:
    
# results
    
Here's the plot of position as a function of time.
In [18]:
    
def plot_results(results):
    xs = results.V_out.index
    ys = results.V_out.values
    t_end = get_last_label(results)
    if t_end < 10:
        xs *= 1000
        xlabel = 'Time (ms)'
    else:
        xlabel = 'Time (s)'
        
    plot(xs, ys)
    decorate(xlabel=xlabel,
             ylabel='$V_{out}$ (volt)',
             legend=False)
    
plot_results(results)
    
    
And velocity as a function of time:
In [19]:
    
fs = [1, 10, 100, 1000, 10000, 100000]
for i, f in enumerate(fs):
    system = make_system(Params(params, f=f))
    ts = linspace(0, system.t_end, 301)
    results, details = run_ode_solver(system, slope_func, t_eval=ts)
    subplot(3, 2, i+1)
    plot_results(results)
    
    
    
In [ ]: