Demo 9: Line and Surface Integrals of Scalar Functions#
Demo by Christian Mikkelstrup, Hans Henrik Hermansen, Jakob Lemvig, Karl Johan Måstrup Kristensen, and Magnus Troen
from sympy import *
from dtumathtools import*
init_printing()
x,y,z = symbols('x y z', real=True)
Curve Lengths#
We are given a parameter curve,
u,v = symbols('u v', real=True)
r = Matrix([sin(u), sin(u)*cos(u)])
r
where \(u \in [0, 2\pi]\).
p_curve = dtuplot.plot_parametric(*r, (u,0,2*pi), use_cm=False, label="r(u)",axis_center="auto")
![../_images/0514b5040ef9db4c80a3445c1e72d023700318f4630a4fd5eb81157575e8a4fa.png](../_images/0514b5040ef9db4c80a3445c1e72d023700318f4630a4fd5eb81157575e8a4fa.png)
Tangent Vector and Tangent#
We find the tangent vector,
dr = r.diff(u)
dr
We now find the parametric representation for the tangent corresponding to the curve point \(r(\pi/3)\),
t = symbols("t")
r_tan = r.subs(u,pi/3) + t*dr.subs(u,pi/3)
r_tan
p_point = dtuplot.scatter(r.subs(u,pi/3), show=False)
p_tan = dtuplot.plot_parametric(*r_tan, (t,-1,1), use_cm=False, label="r '(pi/3)", show=False)
(p_curve + p_point + p_tan).show()
![../_images/cd621f25dc28f421fd3c544ef0c41dbf331ea1666ee6e12f7687073f238fa222.png](../_images/cd621f25dc28f421fd3c544ef0c41dbf331ea1666ee6e12f7687073f238fa222.png)
Length of the Curve#
And then the length of this curve can be found by
Jacobian = dtutools.l2_norm(dr)
integrate(Jacobian, (u,0,2*pi)).n()
![../_images/970ab74c9761206dba47c4d66f2d081487f5d366075a5206f767d8b9fe1bb351.png](../_images/970ab74c9761206dba47c4d66f2d081487f5d366075a5206f767d8b9fe1bb351.png)
Line Integral in 3D space#
We are given a function:
x,y,z = symbols("x y z")
f = lambda x,y,z: sqrt(x**2 + y**2 + z**2)
f(x,y,z)
![../_images/5bff1bf48475d5fc9adb6865d54e242a55432c05168ed8fb994a01bd376999f0.png](../_images/5bff1bf48475d5fc9adb6865d54e242a55432c05168ed8fb994a01bd376999f0.png)
and a parameter curve (a so-called space curve)
r = Matrix([u*cos(u), u*sin(u), u])
r
for \(u\in[0,5]\).
p_spacecurve = dtuplot.plot3d_parametric_line(*r, (u,0,2*pi), use_cm=False, label="r(u)",aspect="equal", legend=True)
![../_images/7a27e8ca8191d051fda204c2866597053f6d61c041eff76014c5479be5129116.png](../_images/7a27e8ca8191d051fda204c2866597053f6d61c041eff76014c5479be5129116.png)
The restriction of the function to the curve is:
restriction = f(*r).simplify()
restriction
![../_images/5645ceb1e37c77d1527e159b20719e5bf92537268ea7e90b6b460803990b99cb.png](../_images/5645ceb1e37c77d1527e159b20719e5bf92537268ea7e90b6b460803990b99cb.png)
and if one remembers that \(u\) is positive, since we have defined \(u\in [0, 5]\), then the absolute value is irrelevant. From the definitions of our u
and v
we do though have them defined by
u,v = symbols('u v', real=True)
where Sympy only takes into account the assumption that \(u=|u|\) in exactly this case. If we had defined them using
u,v = symbols('u v', real=True, nonnegative=True)
instead, we could have used refine()
and Q.\textit{assumption}(symbol)
, where assumption
can be replaced by the entries in this table.
We shall here use Q.nonnegative()
, and then Sympy shows that the restriction in fact is
true_restriction = refine(restriction, Q.nonnegative(u)) # Q.nonnegative(u) tells refine() that u >= 0
true_restriction
![../_images/af03a64ac56cab269f1bef3975e8a8bd95a68922aebbb7f9a7072aefcf849391.png](../_images/af03a64ac56cab269f1bef3975e8a8bd95a68922aebbb7f9a7072aefcf849391.png)
for \(u \in [0,5]\). Whether we write \(u\) or \(|u|\) in the expression can sometimes make a difference if Sympy tries to integrate it.
Let’s return to the line integral that we wish to compute: \(\int_K f(x,y,z)\, \mathrm{d}\pmb{s}\).
First, we find the tangent vector,
dr = r.diff(u)
dr
The length of the tangent vector \(||r_u'(u)||\) is equal to the Jacobian,
Jacobian = dtutools.l2_norm(dr).simplify()
# The following lines only works if $u$ is a real variable
# meaning if 'u = symbols('u', real=True)':
# Jacobian = dr.norm()
Jacobian
![../_images/6eaad6b6fc4bdadae770bc8216c3272eecc4f4c8811211d0ba989241d3443146.png](../_images/6eaad6b6fc4bdadae770bc8216c3272eecc4f4c8811211d0ba989241d3443146.png)
We can now find the integral along the curve,
integrate( f(*r) * Jacobian ,(u,0,5)).evalf()
![../_images/7004f4a94fa85c37b440bd5d787161a60cdf4810354c10b380cd9578623cef78.png](../_images/7004f4a94fa85c37b440bd5d787161a60cdf4810354c10b380cd9578623cef78.png)
and the length of the curve,
integrate(Jacobian,(u,0,5)).evalf()
![../_images/8c29ac36692f6c409bc2612b8d3d94b4e5639a7bebc65992be88b58bdfd3a494.png](../_images/8c29ac36692f6c409bc2612b8d3d94b4e5639a7bebc65992be88b58bdfd3a494.png)
Integral over Cylinder Surface in \(\mathbb{R}^3\)#
We consider a function \(f: \mathbb{R}^3 \to \mathbb{R}\) given by
We also consider a surface given by the following parametric representation with \(u \in [0,\frac{\pi}{2}]\) and \(v \in [0,1]\):
# This time we remember 'nonnegative=True', since we again see that
# none of the intervals for u and v contain negative numbers
u,v = symbols('u v', real=True, nonnegative=True)
r = Matrix([u*cos(u),u*sin(u),u*v])
def f(x,y,z):
return 8*z
r, f(x,y,z)
dtuplot.plot3d_parametric_surface(*r,(u,0,pi/2),(v,0,1), aspect='equal')
![../_images/1939d2c9f9dae9cec85a9798fa514e98ee2281c02d0e31c42fee6461ead37d95.png](../_images/1939d2c9f9dae9cec85a9798fa514e98ee2281c02d0e31c42fee6461ead37d95.png)
<spb.backends.matplotlib.matplotlib.MatplotlibBackend at 0x7f5b4bf525b0>
Side Note: Interactive 3D plots#
Note: This is not needed. Personally, though, we think that it is nice to be able to turn and rotate 3D plots, and have a better overview over what is happening in the plot.
Second note: Apart from that, one also must be aware that one’s notebook cannot be exported to PDF, if one has plots of this type in the document. There are work-arounds for this, but do consider whether you want to spend time on figuring it out.
If one wants to be able to move a 3D plot in order to achieve a better sense of the plot, it is an option to use another backend
when plotting. This does though require that one installs the package plotly
with pip:
pip install plotly
Or by removing the commenting from the cell below and execute it a single time. Then plotly
will be installed in the version of Python that your notebook is using right now.
# ! pip install plotly
# vvvvvvvvvvvvvvvvvv here
# dtuplot.plot3d_parametric_surface(*r,(u,0,pi/2),(v,0,1), aspect='equal', backend=dtuplot.PB, use_cm=True)
The Jacobian of a Surface in 3D#
We find the Jacobian and insert the parametric representation in \(f\):
crossproduct = r.diff(u).cross(r.diff(v))
Jacobian = sqrt((crossproduct.T * crossproduct)[0]).simplify()
Jacobian
![../_images/72be0fd5f14a63ecdccb3adaa95dbb7227630b8a810df27cb50bc4594d746383.png](../_images/72be0fd5f14a63ecdccb3adaa95dbb7227630b8a810df27cb50bc4594d746383.png)
integrand = f(*r) * Jacobian
integrand
![../_images/205cc1814b40e364d0023cefec76537a5df4e4423af7f741ea81a3806f9feff6.png](../_images/205cc1814b40e364d0023cefec76537a5df4e4423af7f741ea81a3806f9feff6.png)
integrate(integrand,(v,0,1),(u,0,pi/2)).evalf()
![../_images/92ce73bf597d8a209ce3918896bc34577cc2efb51b9a0b84a772a77541cfc40e.png](../_images/92ce73bf597d8a209ce3918896bc34577cc2efb51b9a0b84a772a77541cfc40e.png)