In [1]:
%display latex

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
load('https://omega0.xyz/omega8008/sage/sim.sage')
x,y,z = var("x,y,z")

def Surf_Int(F,S,param_u,param_v,evaluate=True):
    r"""
    Surface Integral of vec. Field F through the surface S.
    
    Returns the flux of the vector field F through the
    parametric surface S. The range of parameters is given
    by param_u = (u,u0,u1) and param_v=(v,v0,v1). The
    surface is given by S(u,v) = (x(u,v),y(u,v),z(u,v)) and 
    the field as F(x,y,z) = (P(x,y,z),Q(x,y,z),R(x,y,z)).

    EXAMPLE:
    sage: F(a,b,c)=(c-a,0,c-a)
    sage: S(r,t)=(r*cos(t),r*sin(t),r^2)
    sage: Surf_Int(F,S,(r,0,1),(t,2*pi,0))

    it returns -pi. 
    This is the flux of the vector field (z-x,0,z-x) through the
    surface z = x^2+y^2, z < 1 with outward normal corresponding to
    a c.w. orientation of its boundary (the unit circle on the plane z=1).
    
    Notice how the orientation of the surface is controlled
    by the parameters range; (t,2*pi,0) goes c.w. as opposed
    to (t,0,2*pi) which goes c.c.w.

    EXAMPE 2:
    	   Same as above but with different parametrization for S.
sage: F(a,b,c)=(c-a,0,c-a)
sage: assume(abs(x)<1)
sage: T(x,y)=(x,y,x^2+y^2)
sage: py=(y,-sqrt(1-x^2),sqrt(1-x^2))
sage: Surf_Int(F,T,py,(x,1,-1))
    
    AUTHOR:
        Carlos Rodriguez. 12/01/2012.
    """

    u = param_u[0]
    v = param_v[0]
    D = CoordinatePatch((u,v))
    UV = DifferentialForms(D)
    x_ = DifferentialForm(UV,0,S(u,v)[0])
    y_ = DifferentialForm(UV,0,S(u,v)[1])
    z_ = DifferentialForm(UV,0,S(u,v)[2])
    dx = diff(x_)
    dy = diff(y_)
    dz = diff(z_)
    vF = vector(F(x,y,z))
    vF = vF.subs(x=S(u,v)[0],y=S(u,v)[1],z=S(u,v)[2])
    dydz = dy.wedge(dz)[0,1]
    dzdx = dz.wedge(dx)[0,1]
    dxdy = dx.wedge(dy)[0,1]
    dS = vector([dydz,dzdx,dxdy])
    if evaluate:
       return integral(integral(vF*dS,param_u),param_v)
    else:
       return ("integral",vF*dS,param_u,param_v)


def Surf_Intds(F,S,param_u,param_v,evaluate=True):
    r"""
    Surface Integral of scalar Field F on the surface S.
    
    Returns the integral of the scalar field F on the
    parametric surface S. The range of parameters is given
    by param_u = (u,u0,u1) and param_v=(v,v0,v1). The
    surface is given by S(u,v) = (x(u,v),y(u,v),z(u,v)) and 
    the field as e.g F(x,y,z) = x*y+z

    EXAMPLE:
sage: F(a,b,c)= c-a
sage: S(r,t)=(r*cos(t),r*sin(t),r^2)
sage: Surf_Intds(F,S,(r,0,1),(t,2*pi,0))

    it returns  
    This is the integral of the scalar field z-x through the
    surface z = x^2+y^2, z < 1 with outward normal corresponding to
    a c.w. orientation of its boundary (the unit circle on the plane z=1).
    
    Notice how the orientation of the surface is controlled
    by the parameters range; (t,2*pi,0) goes c.w. as opposed
    to (t,0,2*pi) which goes c.c.w.

    EXAMPE 2:
    	   Same as above but with different parametrization for S.
sage: F(a,b,c)= c-a
sage: assume(abs(x)<1)
sage: T(x,y)=(x,y,x^2+y^2)
sage: py=(y,-sqrt(1-x^2),sqrt(1-x^2))
sage: Surf_Intds(F,T,py,(x,1,-1))
    
    AUTHOR:
        Carlos Rodriguez. 12/01/2012.
    """

    u = param_u[0]
    v = param_v[0]
    D = CoordinatePatch((u,v))
    UV = DifferentialForms(D)
    x_ = DifferentialForm(UV,0,S(u,v)[0])
    y_ = DifferentialForm(UV,0,S(u,v)[1])
    z_ = DifferentialForm(UV,0,S(u,v)[2])
    dx = diff(x_)
    dy = diff(y_)
    dz = diff(z_)
    # vF = vector(F(x,y,z))
    vF = F(x,y,z).subs(x=S(u,v)[0],y=S(u,v)[1],z=S(u,v)[2])
    dydz = dy.wedge(dz)[0,1]
    dzdx = dz.wedge(dx)[0,1]
    dxdy = dx.wedge(dy)[0,1]
    dS = vector([dydz,dzdx,dxdy]).norm().full_simplify().full_simplify()
    if evaluate:
       return integral(integral(vF*dS,param_u),param_v)
    else:
       return ("integral",vF*dS,param_u,param_v)

def curl(F):
    r"""
    Returns curl F as a tuple field

    EXAMPLE:
    sage: a,b,c=var('a,b,c')
    sage: F(x,y,z)=(x*y,x*z,y*z)
    sage: curlF(x,y,z)=curl(F)
    sage: curlF(a,b,c)

    AUTHOR: Carlos Rodriguez. 12/01/2012.
    """
    
    F1=F(x,y,z)[0]
    F2=F(x,y,z)[1]
    F3=F(x,y,z)[2]
    c1 = diff(F3,y)-diff(F2,z)
    c2 = diff(F1,z)-diff(F3,x)
    c3 = diff(F2,x)-diff(F1,y)
    return (c1,c2,c3)
    

def Line_Int(F,C,param_t,evaluate=True):
    r"""
    Line Integral of vec. Field F along parameterized curve C.

    Returns the value of \int_{C} F.dr
    The vector field is given as a 3-tuple field. e.g.
    F(x,y,z) = (x*y,y*z,x*z)
    The curve is also given as a 3-tuple field. e.g.
    C(t)=(cos(t),3*sin(t),t)
    and the range of the parameter is given as, e.g.,
    param_t=(t,0,pi).

    EXAMPLE: with the above choices:
sage: F(x,y,z) = (x*y,y*z,x*z)
sage: C(t)=(cos(t),3*sin(t),t)
sage: param_t=(t,0,pi)
sage: Line_Int(F,C,param_t)
     returns -1/4 pi - 2.


    AUTHOR: Carlos Rodriguez. 12/02/2012.

    """

    t = param_t[0]
    dx = diff(C(t)[0],t)
    dy = diff(C(t)[1],t)
    dz = diff(C(t)[2],t)
    dr = vector([dx,dy,dz])
    vF = vector(F(x,y,z))
    vF = vF.subs(x=C(t)[0],y=C(t)[1],z=C(t)[2])
    if evaluate:
       return integral(vF*dr,param_t)
    else:
       return ("integral",vF*dr,param_t)


def Line_Intds(f,C,param_t,evaluate=True):
    r"""
    Line Integral of scalar field f along parameterized curve C.

    Returns the value of \int_{C} f.ds
    The scalar field is given as, e.g.
    f(x,y,z) = x*y+y*z+x*z
    The curve is given as a 3-tuple field. e.g.
    C(t)=(cos(t),3*sin(t),t)
    and the range of the parameter is given as, e.g.,
    param_t=(t,0,pi/4).

    EXAMPLE: with the above choices:
sage: f(x,y,z) = x*y+y*z+x*z
sage: C(t)=(cos(t),3*sin(t),t)
sage: param_t=(t,0,pi/4)
sage: Line_Intds(f,C,param_t)
     returns 1/4*((4*sqrt(2)) + 1)*sqrt(2) - sqrt(2)

sage: g(x,y,z)=1
sage: Line_Intds(g,C,(t,0,pi))
     returns the length of C:  pi*sqrt(2)


    AUTHOR: Carlos Rodriguez. 12/02/2012.

    """

    t = param_t[0]
    ds = diff(C(t),t).norm()
    ds = Sim(ds)
    vf = f(x,y,z).subs(x=C(t)[0],y=C(t)[1],z=C(t)[2])
    if evaluate:
       return integral(vf*ds,param_t)
    else:
       return ("integral",vf*ds,param_t)
In [3]:
sage: F(a,b,c)= c-a
sage: assume(abs(x)<1)
sage: T(x,y)=(x,y,x^2+y^2)
sage: py=(y,-sqrt(1-x^2),sqrt(1-x^2))
sage: Surf_Intds(F,T,py,(x,1,-1))
Out[3]:

Tough cookie?: (well.. wrong coord system really)

Not really. For some weird reason Maxima doesn't like to integrate backwards: $(x,1,-1)$.

Just watch:

In [39]:
-Surf_Intds(F,T,py,(x,-1,1))
Out[39]:

Voila! Done

In [24]:
sage: F(a,b,c)=(c-a,0,c-a)
sage: S(r,t)=(r*cos(t),r*sin(t),r^2)
sage: Surf_Int(F,S,(r,0,1),(t,2*pi,0))
Out[24]:
In [7]:
sage: assume(abs(x)<1)
sage: T(x,y)=(x,y,x^2+y^2)
sage: py=(y,-sqrt(1-x^2),sqrt(1-x^2))
sage: Surf_Int(F,T,py,(x,1,-1))
Out[7]:

Same as above: (But now in the natural coordinates)

Notice that now Maxima doesn't mind integrating backwards (c.w. as oppose to the usual c.c.w.): $(t,2\pi,0)$

In [8]:
sage: F(a,b,c)= c-a
sage: S(r,t)=(r*cos(t),r*sin(t),r^2)
sage: Surf_Intds(F,S,(r,0,1),(t,2*pi,0))
Out[8]:
In [9]:
sage: a,b,c=var('a,b,c')
sage: F(x,y,z)=(x*y,x*z,y*z)
sage: curlF(x,y,z)=curl(F)
sage: curlF(a,b,c)
Out[9]:
In [10]:
sage: F(x,y,z) = (x*y,y*z,x*z)
sage: C(t)=(cos(t),3*sin(t),t)
sage: param_t=(t,0,pi)
sage: Line_Int(F,C,param_t)
Out[10]:
In [3]:
# Let's clear the vars... just in case?
sage: x,y,z,t = var('x,y,z,t')
sage: f(x,y,z) = x*y+y*z+x*z
sage: C(t)=(cos(t),3*sin(t),t)
sage: param_t=(t,0,pi/4)
sage: Line_Intds(f,C,param_t)
In [0]: