Modeling and Simulation in Python

Copyright 2018 Allen Downey

``````

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

``````