Compute divergence of vector field using python

前端 未结 10 2672
甜味超标
甜味超标 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:19

    I don't think the answer by @Daniel is correct, especially when the input is in order [Fx, Fy, Fz, ...].

    A simple test case

    See the MATLAB code:

    a = [1 2 3;1 2 3; 1 2 3];
    b = [[7 8 9] ;[1 5 8] ;[2 4 7]];
    divergence(a,b)
    

    which gives the result:

    ans =
    
       -5.0000   -2.0000         0
       -1.5000   -1.0000         0
        2.0000         0         0
    

    and Daniel's solution:

    def divergence(f):
        """
        Daniel's solution
        Computes the divergence of the vector field f, corresponding to dFx/dx + dFy/dy + ...
        :param f: List of ndarrays, where every item of the list is one dimension of the vector field
        :return: Single ndarray of the same shape as each of the items in f, which corresponds to a scalar field
        """
        num_dims = len(f)
        return np.ufunc.reduce(np.add, [np.gradient(f[i], axis=i) for i in range(num_dims)])
    
    
    if __name__ == '__main__':
        a = np.array([[1, 2, 3]] * 3)
        b = np.array([[7, 8, 9], [1, 5, 8], [2, 4, 7]])
        div = divergence([a, b])
        print(div)
        pass
    

    which gives:

    [[1.  1.  1. ]
     [4.  3.5 3. ]
     [2.  2.5 3. ]]
    

    Explanation

    The mistake of Daniel's solution is, in Numpy, the x axis is the last axis instead of the first axis. When using np.gradient(x, axis=0), Numpy actually gives the gradient of y direction (when x is a 2d array).

    My solution

    There is my solution based on Daniel's answer.

    def divergence(f):
        """
        Computes the divergence of the vector field f, corresponding to dFx/dx + dFy/dy + ...
        :param f: List of ndarrays, where every item of the list is one dimension of the vector field
        :return: Single ndarray of the same shape as each of the items in f, which corresponds to a scalar field
        """
        num_dims = len(f)
        return np.ufunc.reduce(np.add, [np.gradient(f[num_dims - i - 1], axis=i) for i in range(num_dims)])
    

    which gives the same result as MATLAB divergence in my test case.

提交回复
热议问题