Modeling and Simulation in Python

Copyright 2018 Allen Downey

License: Creative Commons Attribution 4.0 International


In [1]:
# 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 *

The duck problem


In [2]:
g = UNITS.g
cm = UNITS.cm


Out[2]:
centimeter

In [3]:
system = System (
    density_duck = 0.3 * g/cm**3,
    density_water = 1  * g/cm**3,
    r = 5 * cm,
)


Out[3]:
values
density_duck 0.3 gram / centimeter ** 3
density_water 1.0 gram / centimeter ** 3
r 5 centimeter

In [4]:
def error_func(d, system):
    # in order to work with root_scale, we have
    # to accept input that does not have units
    d = d * cm
    r = system.r
    
    volume_duck = 4 / 3 * pi * r**3
    mass_duck = volume_duck * system.density_duck

    volume_water = pi / 3 * (3 * r * d**2 - d**3)
    mass_water = volume_water * system.density_water

    # and return an error that does not have units
    error = mass_duck - mass_water
    return magnitude(error)

In [5]:
error_func(3, system)


Out[5]:
43.982297150257125

In [6]:
error_func(4, system)


Out[6]:
-27.227136331111524

In [7]:
res = root_scalar(error_func, [3., 4.], system)


Out[7]:
      converged: True
           flag: 'converged'
 function_calls: 7
     iterations: 6
           root: 3.6325749109061265

In [8]:
res.root * cm


Out[8]:
3.6325749109061265 centimeter