用Python的NumPy和Matplotlib,5分钟可视化理解矢量场的‘源’与‘汇’(散度实战)

矢量场的"源"与"汇"是电磁学、流体力学等领域的核心概念,但传统数学推导往往让学习者望而生畏。本文将用Python的NumPy和Matplotlib,通过代码实战带您直观理解这一抽象概念。无需复杂理论,只需基础Python知识,您就能在Jupyter Notebook中创建生动的可视化效果,亲眼看到矢量场如何从"源"发散、向"汇"汇聚。

1. 环境准备与基础概念

在开始编码前,我们先快速配置环境并理解关键术语。推荐使用Anaconda创建干净的Python 3.8+环境,安装以下包:

pip install numpy matplotlib ipywidgets

矢量场 可以想象为空间中每点都有一个箭头,表示该点的矢量(如电场强度、流速等)。而 散度 (divergence)则量化了矢量场的"发散程度":

  • 正散度 :矢量从该点向外发散,称为"源"
  • 负散度 :矢量向该点汇聚,称为"汇"
  • 零散度 :矢量平行通过,无净流出/流入

在直角坐标系中,矢量场F = (F_x, F_y, F_z)的散度计算公式为:

div F = ∂F_x/∂x + ∂F_y/∂y + ∂F_z/∂z

2. 构建点电荷电场模型

我们以点电荷产生的电场为例,这是典型的径向矢量场。在二维平面上,点电荷位于原点时,电场强度E与距离r成反比:

import numpy as np

def electric_field(x, y, q=1):
    """计算点电荷电场矢量"""
    r = np.sqrt(x**2 + y**2)
    r3 = np.where(r > 0, r**3, 1)  # 避免除以零
    Ex = q * x / r3
    Ey = q * y / r3
    return Ex, Ey

对应的散度理论值在原点外应为零(无电荷区域),在原点处为狄拉克δ函数。我们可以用NumPy实现数值计算:

def divergence(fx, fy, dx=0.1):
    """数值计算二维矢量场散度"""
    dfx_dx = np.gradient(fx, dx, axis=1)
    dfy_dy = np.gradient(fy, dx, axis=0)
    return dfx_dx + dfy_dy

3. 可视化矢量场与散度分布

现在进入最激动人心的部分——可视化。我们将创建包含三个子图的复合可视化:

  1. 矢量箭头图 :显示电场方向与强度
  2. 散度热力图 :用颜色表示发散强度
  3. 流线图 :展示场线分布
import matplotlib.pyplot as plt

# 创建坐标网格
x = np.linspace(-2, 2, 20)
y = np.linspace(-2, 2, 20)
X, Y = np.meshgrid(x, y)

# 计算电场和散度
Ex, Ey = electric_field(X, Y)
div = divergence(Ex, Ey)

# 创建可视化
plt.figure(figsize=(15, 5))

# 子图1:矢量箭头
plt.subplot(131)
plt.quiver(X, Y, Ex, Ey, scale=30, color='blue')
plt.title('电场矢量分布')
plt.xlabel('x'); plt.ylabel('y')

# 子图2:散度热力图
plt.subplot(132)
plt.pcolormesh(X, Y, div, cmap='RdBu', shading='auto')
plt.colorbar(label='散度值')
plt.title('散度分布热图')
plt.xlabel('x'); plt.ylabel('y')

# 子图3:流线图
plt.subplot(133)
plt.streamplot(X, Y, Ex, Ey, color='green', density=1.5)
plt.title('电场流线图')
plt.xlabel('x'); plt.ylabel('y')

plt.tight_layout()
plt.show()

运行这段代码,您将看到三幅相互印证的图像,直观展示正电荷如何作为"源"产生电场。尝试修改电荷量q为负值,观察"汇"的效果。

4. 进阶应用:自定义矢量场分析

理解了基本原理后,我们可以探索更复杂的矢量场。比如考虑两个点电荷构成的电偶极子:

def dipole_field(x, y, q1=1, q2=-1, d=1):
    """计算电偶极子电场"""
    # 正电荷位置 (d/2, 0)
    Ex1, Ey1 = electric_field(x - d/2, y, q1)
    # 负电荷位置 (-d/2, 0)
    Ex2, Ey2 = electric_field(x + d/2, y, q2)
    return Ex1 + Ex2, Ey1 + Ey2

可视化时,我们还可以添加交互功能,实时观察参数变化的影响:

from ipywidgets import interact

@interact(q1=(-2, 2, 0.1), q2=(-2, 2, 0.1), d=(0.1, 2, 0.1))
def plot_interactive(q1=1, q2=-1, d=1):
    Ex, Ey = dipole_field(X, Y, q1, q2, d)
    div = divergence(Ex, Ey)
    
    plt.figure(figsize=(10, 8))
    plt.pcolormesh(X, Y, div, cmap='RdBu', alpha=0.7)
    plt.colorbar(label='散度值')
    plt.streamplot(X, Y, Ex, Ey, color='black', density=2)
    plt.scatter([d/2, -d/2], [0, 0], c=['red', 'blue'], s=100)
    plt.title(f'电偶极子场 (q1={q1}, q2={q2}, d={d})')
    plt.xlabel('x'); plt.ylabel('y')
    plt.show()

这种交互式可视化让抽象概念变得触手可及。您可以尝试:

  • 设置q1=q2=1,观察两个"源"的相互作用
  • 调整距离d,感受场分布如何变化
  • 修改电荷量比例,分析场线模式变化

5. 实际应用场景与扩展思路

理解矢量场的散度不仅具有理论价值,在多个领域都有实际应用:

工程流体分析 :通过速度场的散度识别流体中的源(喷口)和汇(排水口)

# 简单流体场示例:源+汇
def fluid_flow(x, y):
    # 源 (x=1, y=1)
    r1 = np.sqrt((x-1)**2 + (y-1)**2)
    vx1 = (x-1) / (r1 + 0.1)**2
    vy1 = (y-1) / (r1 + 0.1)**2
    
    # 汇 (x=-1, y=-1)
    r2 = np.sqrt((x+1)**2 + (y+1)**2)
    vx2 = -(x+1) / (r2 + 0.1)**2
    vy2 = -(y+1) / (r2 + 0.1)**2
    
    return vx1 + vx2, vy1 + vy2

气象学 :大气速度场的散度帮助预测高压(源)和低压(汇)系统

电磁仿真 :通过电场/磁场散度验证麦克斯韦方程组的数值解

对于想深入研究的读者,可以尝试以下扩展:

  1. 实现三维矢量场可视化(使用matplotlib的3D功能)
  2. 添加导体边界条件,观察场分布变化
  3. 结合梯度、旋度等概念,构建完整的矢量分析工具包
  4. 使用PyQt或Dash构建更友好的交互界面

更多推荐