The problem

I am trying to apply point load in FEniCS. It’s a load term and thus couldnot be applied as DirichletBC and pointwise in FEniCS. The PointSource method also limits us to application of a single term and we need to hack our way out from vector terms. Also, from what I understand the PointSource is applied on assembled system. But, I would like to apply the load in the variational form.

The solution

We can use UserExpression to define an expression that would be zero everywhere on the mesh and equal the the load at the point of application. This could be achieved with the following code snippet

class PointLoad(UserExpression):
    def __init__(self, pt, vl,tol,**kwargs):
        super().__init__(**kwargs)
        self.point = pt
        self.value = vl
        self.tol = tol
    def eval(self, values, x):
        if near (x[0], self.point[0],self.tol) and near(x[1], self.point[1],self.tol):
            values[0] = self.value[0]
            values[1] = self.value[1]
        else:
            values[0] = 0
            values[1] = 0
    def value_shape(self):
        return (2,)

The class PointLoad is inherited from the UserExpression class. It is important to call the super().__init__(**kwargs) method to inherit all the functionality of the parent class. The eval method contains the logic for the evaluation of the expression over the mesh. It takes in the co-ordinate vector x and the values vector values.The expression is evaluated on each vertex of the mesh, and thus, if we specify the load vertices we can apply the point load as follows

f0 = PointLoad(pt=(2.5,0), vl=(a0,b0), tol=1e-1,degree = 1)
l = dot(f0,v)*dx

References