How to calculate the integral of a vector field along a path?

Hello, everyone. I want to calculate the integral of a vector field along a path.


How can I get the unit vector along the boundary as the figure shows ? I have tried ufl.classes.CellEdgeVectors, it returns a (3,3) shape ufl object. I have tried to multiple one of its component to the vector field and I always got zero. Here is my code.

import gmsh 
import dolfinx, ufl
from mpi4py import MPI
import numpy as np
import ufl.classes 
R = 1.0
grid_size = 0.2
order = 2

gmsh.initialize()
gmsh.model.add("hemi_sphere")
sphere = gmsh.model.occ.add_sphere(0.0, 0.0, 0.0, R)
box = gmsh.model.occ.add_box(-R-0.1, -R-0.1, 0, 2*R+0.1, 2*R+0.1, R+0.1)
result = gmsh.model.occ.intersect([(3, sphere)], [(3, box)])
gmsh.model.occ.synchronize()

surfaces = gmsh.model.getEntities(dim=2)
for surface in surfaces:
    com = gmsh.model.occ.getCenterOfMass(surface[0], surface[1])
    if np.allclose(com, [0, 0, 0]): # 平面
        plane = surface
        gmsh.model.addPhysicalGroup(surface[0], [surface[1]], 10, "circle")
    elif np.allclose(com, [0.0, 0.0, R*0.5]):
        hemi_sphere = surface
        gmsh.model.addPhysicalGroup(surface[0], [surface[1]], 20, "hemi_sphere")

boundary = gmsh.model.getBoundary([(plane[0], plane[1])])
gmsh.model.addPhysicalGroup(1, [b[1] for b in boundary], 1, "boundary")

gmsh.option.setNumber("Mesh.CharacteristicLengthMax", grid_size)
gmsh.model.mesh.generate(2)
gmsh.model.mesh.setOrder(order)
mesh, cell_marker, facet_marker = dolfinx.io.gmshio.model_to_mesh(gmsh.model, MPI.COMM_WORLD, 0, gdim=3)
gmsh.finalize()

dx = ufl.Measure("dx", domain=mesh, subdomain_data=cell_marker)
x = ufl.SpatialCoordinate(mesh)
zero = dolfinx.fem.Constant(mesh, dolfinx.default_scalar_type(0.0))
F = ufl.as_vector([-x[1], x[0], zero])
cell_normal_vector = ufl.CellNormal(mesh)

form2 = dolfinx.fem.form(ufl.dot(ufl.curl(F), cell_normal_vector)* dx(10)) 
print(dolfinx.fem.assemble_scalar(form2))

ds = ufl.Measure("ds", subdomain_data=facet_marker)
cell_edge_vector = ufl.classes.CellEdgeVectors(mesh)
# This is always zero. I have tried cell_edge_vector[0, :], cell_edge_vector[1, :]
# or cell_edge_vector[:, 0], cell_edge_vector[:, 1], cell_edge_vector[:, 2]
form = dolfinx.fem.form(ufl.dot(cell_edge_vector[2, :], F) * ufl.ds)
print(dolfinx.fem.assemble_scalar(form))

Your image says you want to integral the vector \vec{F},
\int_C \vec{F} \cdot d\vec{l}
which is
\int_C \vec{F} \cdot \vec{n} \, dl

But your code is trying to integrate the curl of \vec{F},

i.e. it’s integrating \nabla \times \vec{F} not \vec{F}

Isn’t it supposed to be exactly the same quantity according to Stokes theorem?

True, if dx(10) is the area of the circle not the line (the boundary) of the circle then it should be fine. I was reading it as the latter.

Yes, but this line, I am trying to calculate \int \vec{F}\cdot \mathrm{d}\vec{l}

I want to verify Stokes theorem numerically.
Maybe it’s impossible to calculate this integral by fenics, becase the mesh does not contain the derivative of the boundary curve and it’s also expensive to calculate the derivatives.