Compute divergence of vector field using python

前端 未结 10 2667
甜味超标
甜味超标 2020-12-03 21:58

Is there a function that could be used for calculation of the divergence of the vectorial field? (in matlab) I would expect it exists in numpy/scipy but I can not find it us

10条回答
  •  鱼传尺愫
    2020-12-03 22:24

    The answer of @user2818943 is good, but it can be optimized a little:

    def divergence(F):
        """ compute the divergence of n-D scalar field `F` """
        return reduce(np.add,np.gradient(F))
    

    Timeit:

    F = np.random.rand(100,100)
    timeit reduce(np.add,np.gradient(F))
    # 1000 loops, best of 3: 318 us per loop
    
    timeit np.sum(np.gradient(F),axis=0)
    # 100 loops, best of 3: 2.27 ms per loop
    

    About 7 times faster: sum implicitely construct a 3d array from the list of gradient fields which are returned by np.gradient. This is avoided using reduce


    Now, in your question what do you mean by div[A * grad(F)]?

    1. about A * grad(F): A is a 2d array, and grad(f) is a list of 2d arrays. So I considered it means to multiply each gradient field by A.
    2. about applying divergence to the (scaled by A) gradient field is unclear. By definition, div(F) = d(F)/dx + d(F)/dy + .... I guess this is just an error of formulation.

    For 1, multiplying summed elements Bi by a same factor A can be factorized:

    Sum(A*Bi) = A*Sum(Bi)
    

    Thus, you can get this weighted gradient simply with: A*divergence(F)

    If ̀A is instead a list of factor, one for each dimension, then the solution would be:

    def weighted_divergence(W,F):
        """
        Return the divergence of n-D array `F` with gradient weighted by `W`
    
        ̀`W` is a list of factors for each dimension of F: the gradient of `F` over
        the `i`th dimension is multiplied by `W[i]`. Each `W[i]` can be a scalar
        or an array with same (or broadcastable) shape as `F`.
        """
        wGrad = return map(np.multiply, W, np.gradient(F))
        return reduce(np.add,wGrad)
    
    result = weighted_divergence(A,F)
    

提交回复
热议问题